wx affects sprite m3 cycles. cache m3 cycles, related refactoring. readjust cgb dma cycles to previously changed m3 timing. clean up goofy lyc calculation.
git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@113 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
This commit is contained in:
parent
630e0e6c3a
commit
6eb9761b10
BIN
hwtests/dma/dma_src_wrap_out1.gbc
Normal file
BIN
hwtests/dma/dma_src_wrap_out1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx0_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx0_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx0_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx0_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx1_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx1_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx1_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx1_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx2_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx2_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx2_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx2_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx3_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx3_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx3_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx3_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx4_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx4_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx4_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx4_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx5_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx5_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx5_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx5_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx6_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx6_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx6_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx6_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx7_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx7_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/10spritesPrLine_wx7_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/10spritesPrLine_wx7_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/1pos8_8pos9_wx08_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/1pos8_8pos9_wx08_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/1pos8_8pos9_wx08_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/1pos8_8pos9_wx08_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx08_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx08_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx08_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx08_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx08_scx5_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx08_scx5_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx08_scx5_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx08_scx5_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx09_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx09_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx09_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx09_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0A_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0A_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0A_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0A_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0B_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0B_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0B_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0B_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0C_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0C_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0C_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0C_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0D_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0D_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0D_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0D_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0E_m3stat_ds_1.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0E_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/sprites/space/9pos8_wx0E_m3stat_ds_2.gbc
Normal file
BIN
hwtests/sprites/space/9pos8_wx0E_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/vram_m3/prewrite_ds_1.gbc
Normal file
BIN
hwtests/vram_m3/prewrite_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/vram_m3/prewrite_ds_2.gbc
Normal file
BIN
hwtests/vram_m3/prewrite_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_m3stat_1.gbc
Normal file
BIN
hwtests/window/m2int_wx03_m3stat_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_m3stat_2.gbc
Normal file
BIN
hwtests/window/m2int_wx03_m3stat_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_m3stat_ds_1.gbc
Normal file
BIN
hwtests/window/m2int_wx03_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_m3stat_ds_2.gbc
Normal file
BIN
hwtests/window/m2int_wx03_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_scx2_m3stat_1.gbc
Normal file
BIN
hwtests/window/m2int_wx03_scx2_m3stat_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_scx2_m3stat_2.gbc
Normal file
BIN
hwtests/window/m2int_wx03_scx2_m3stat_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_scx3_m3stat_1.gbc
Normal file
BIN
hwtests/window/m2int_wx03_scx3_m3stat_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_scx3_m3stat_2.gbc
Normal file
BIN
hwtests/window/m2int_wx03_scx3_m3stat_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_scx5_m3stat_1.gbc
Normal file
BIN
hwtests/window/m2int_wx03_scx5_m3stat_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_scx5_m3stat_2.gbc
Normal file
BIN
hwtests/window/m2int_wx03_scx5_m3stat_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_scx5_m3stat_ds_1.gbc
Normal file
BIN
hwtests/window/m2int_wx03_scx5_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wx03_scx5_m3stat_ds_2.gbc
Normal file
BIN
hwtests/window/m2int_wx03_scx5_m3stat_ds_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_m3stat_1.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_m3stat_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_m3stat_2.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_m3stat_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_scx2_m3stat_1.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_scx2_m3stat_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_scx2_m3stat_2.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_scx2_m3stat_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_scx3_m3stat_1.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_scx3_m3stat_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_scx3_m3stat_2.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_scx3_m3stat_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_scx5_m3stat_1.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_scx5_m3stat_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_scx5_m3stat_2.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_scx5_m3stat_2.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_scx5_m3stat_ds_1.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_scx5_m3stat_ds_1.gbc
Normal file
Binary file not shown.
BIN
hwtests/window/m2int_wxA6_scx5_m3stat_ds_2.gbc
Normal file
BIN
hwtests/window/m2int_wxA6_scx5_m3stat_ds_2.gbc
Normal file
Binary file not shown.
@ -33,7 +33,6 @@ sourceFiles = Split('''
|
||||
src/video/sc_reader.cpp
|
||||
src/video/scx_reader.cpp
|
||||
src/video/sprite_mapper.cpp
|
||||
src/video/sprite_size_reader.cpp
|
||||
src/video/we_master_checker.cpp
|
||||
src/video/we.cpp
|
||||
src/video/wx_reader.cpp
|
||||
|
@ -1,41 +1,51 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License version 2 as *
|
||||
* published by the Free Software Foundation. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License version 2 for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* version 2 along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "sprite_size_reader.h"
|
||||
|
||||
#include "sprite_mapper.h"
|
||||
#include "basic_add_event.h"
|
||||
|
||||
SpriteSizeReader::SpriteSizeReader(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue_in,
|
||||
SpriteMapper &spriteMapper_in, const LyCounter &lyCounter_in) :
|
||||
VideoEvent(0),
|
||||
m3EventQueue(m3EventQueue_in),
|
||||
spriteMapper(spriteMapper_in),
|
||||
lyCounter(lyCounter_in)
|
||||
{
|
||||
setSource(false);
|
||||
reset();
|
||||
}
|
||||
|
||||
void SpriteSizeReader::doEvent() {
|
||||
largeSprites_ = src_;
|
||||
|
||||
addEvent(spriteMapper, lyCounter, time(), m3EventQueue);
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License version 2 as *
|
||||
* published by the Free Software Foundation. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License version 2 for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* version 2 along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef INSERTION_SORT_H
|
||||
#define INSERTION_SORT_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
template<typename T, class Less>
|
||||
void insertionSort(T *const start, T *const end, Less less) {
|
||||
if (start >= end)
|
||||
return;
|
||||
|
||||
T *a = start;
|
||||
|
||||
while (++a < end) {
|
||||
const T e = *a;
|
||||
|
||||
T *b = a;
|
||||
|
||||
while (b != start && less(e, *(b - 1))) {
|
||||
*b = *(b - 1);
|
||||
b = b - 1;
|
||||
}
|
||||
|
||||
*b = e;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void insertionSort(T *const start, T *const end) {
|
||||
insertionSort(start, end, std::less<T>());
|
||||
}
|
||||
|
||||
#endif /*INSERTION_SORT_H*/
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -339,8 +339,6 @@ unsigned long Memory::event(unsigned long cycleCounter) {
|
||||
unsigned dmaDest = dmaDestination;
|
||||
unsigned dmaLength = ((memory[0xFF55] & 0x7F) + 0x1) * 0x10;
|
||||
|
||||
cycleCounter += (6 >> doubleSpeed) + doubleSpeed;
|
||||
|
||||
unsigned length = hdma_transfer ? 0x10 : dmaLength;
|
||||
|
||||
if (static_cast<unsigned long>(dmaDest) + length & 0x10000) {
|
||||
@ -353,6 +351,8 @@ unsigned long Memory::event(unsigned long cycleCounter) {
|
||||
if (!(memory[0xFF40] & 0x80))
|
||||
dmaLength = 0;
|
||||
|
||||
cycleCounter += 4;
|
||||
|
||||
while (length--) {
|
||||
write(0x8000 | dmaDest++ & 0x1FFF, read(dmaSrc++ & 0xFFFF, cycleCounter), cycleCounter);
|
||||
cycleCounter += 2 << doubleSpeed;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -94,13 +94,10 @@ LCD::LCD(const unsigned char *const oamram, const unsigned char *const vram_in)
|
||||
m3EventQueue(11, VideoEventComparer()),
|
||||
irqEventQueue(4, VideoEventComparer()),
|
||||
vEventQueue(5, VideoEventComparer()),
|
||||
m3ExtraCycles(*this),
|
||||
weMasterChecker(m3EventQueue, wyReg, lyCounter),
|
||||
wyReg(lyCounter, weMasterChecker),
|
||||
wxReader(m3EventQueue, we.enableChecker(), we.disableChecker()),
|
||||
spriteSizeReader(m3EventQueue, spriteMapper, lyCounter),
|
||||
scxReader(m3EventQueue, /*wyReg.reader3(),*/ wxReader, we.enableChecker(), we.disableChecker()),
|
||||
spriteMapper(spriteSizeReader, scxReader, oamram),
|
||||
win(m3EventQueue, lyCounter, m3ExtraCycles),
|
||||
scxReader(m3EventQueue, /*wyReg.reader3(),*/ win.wxReader, win.we.enableChecker(), win.we.disableChecker(), m3ExtraCycles),
|
||||
spriteMapper(m3ExtraCycles, oamram),
|
||||
m3ExtraCycles(spriteMapper, scxReader, win),
|
||||
breakEvent(drawStartCycle, scReadOffset),
|
||||
mode3Event(m3EventQueue, vEventQueue, mode0Irq, irqEvent),
|
||||
lycIrq(ifReg),
|
||||
@ -158,10 +155,10 @@ void LCD::reset(const bool cgb_in) {
|
||||
we = false;*/
|
||||
|
||||
scxReader.setSource(0);
|
||||
wxReader.setSource(0);
|
||||
wyReg.setSource(0);
|
||||
spriteSizeReader.setSource(false);
|
||||
we.setSource(false);
|
||||
win.wxReader.setSource(0);
|
||||
win.wyReg.setSource(0);
|
||||
spriteMapper.setLargeSpritesSource(false);
|
||||
win.we.setSource(false);
|
||||
// weMasterChecker.setSource(false);
|
||||
scReader.setScxSource(0);
|
||||
scReader.setScySource(0);
|
||||
@ -178,8 +175,7 @@ void LCD::setDoubleSpeed(const bool ds) {
|
||||
doubleSpeed = ds;
|
||||
lyCounter.setDoubleSpeed(doubleSpeed);
|
||||
scxReader.setDoubleSpeed(doubleSpeed);
|
||||
wxReader.setDoubleSpeed(doubleSpeed);
|
||||
spriteMapper.setDoubleSpeed(doubleSpeed);
|
||||
win.wxReader.setDoubleSpeed(doubleSpeed);
|
||||
scReader.setDoubleSpeed(doubleSpeed);
|
||||
breakEvent.setDoubleSpeed(doubleSpeed);
|
||||
lycIrq.setDoubleSpeed(doubleSpeed);
|
||||
@ -225,21 +221,20 @@ void LCD::resetVideoState(const unsigned statReg, const unsigned long cycleCount
|
||||
vEventQueue.push(&lyCounter);
|
||||
|
||||
scxReader.reset();
|
||||
wxReader.reset();
|
||||
wyReg.reset();
|
||||
spriteSizeReader.reset();
|
||||
win.wxReader.reset();
|
||||
win.wyReg.reset();
|
||||
spriteMapper.reset();
|
||||
we.reset();
|
||||
win.we.reset();
|
||||
scReader.reset();
|
||||
breakEvent.reset();
|
||||
|
||||
mode3Event.reset();
|
||||
|
||||
weMasterChecker.reset();
|
||||
weMasterChecker.schedule(wyReg.getSource(), we.getSource(), cycleCounter);
|
||||
win.weMasterChecker.reset();
|
||||
win.weMasterChecker.schedule(win.wyReg.getSource(), win.we.getSource(), cycleCounter);
|
||||
|
||||
if (weMasterChecker.time() != VideoEvent::DISABLED_TIME) {
|
||||
m3EventQueue.push(&weMasterChecker);
|
||||
if (win.weMasterChecker.time() != VideoEvent::DISABLED_TIME) {
|
||||
m3EventQueue.push(&win.weMasterChecker);
|
||||
mode3Event.schedule();
|
||||
vEventQueue.push(&mode3Event);
|
||||
}
|
||||
@ -266,6 +261,8 @@ void LCD::resetVideoState(const unsigned statReg, const unsigned long cycleCount
|
||||
|
||||
irqEvent.schedule();
|
||||
vEventQueue.push(&irqEvent);
|
||||
|
||||
m3ExtraCycles.invalidateCache();
|
||||
}
|
||||
|
||||
// static VideoBlitter *vBlitter = NULL;
|
||||
@ -402,24 +399,23 @@ void LCD::rescheduleEvents(const unsigned long cycleCounter) {
|
||||
vEventQueue.push(&lyCounter);
|
||||
|
||||
rescheduleIfActive(scxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(spriteSizeReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(spriteMapper, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(wxReader, scxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(wyReg.reader1(), lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(wyReg.reader2(), lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(win.wxReader, scxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(win.wyReg.reader1(), lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(win.wyReg.reader2(), lyCounter, cycleCounter, m3EventQueue);
|
||||
// rescheduleIfActive(wyReg.reader3(), scxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(wyReg.reader4(), lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(we.disableChecker(), scxReader, wxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(we.enableChecker(), scxReader, wxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(win.wyReg.reader4(), lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(win.we.disableChecker(), scxReader, win.wxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
rescheduleIfActive(win.we.enableChecker(), scxReader, win.wxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
if (wyReg.reader3().time() != VideoEvent::DISABLED_TIME) {
|
||||
wyReg.reader3().schedule(wxReader.getSource(), scxReader, cycleCounter);
|
||||
m3EventQueue.push(&wyReg.reader3());
|
||||
if (win.wyReg.reader3().time() != VideoEvent::DISABLED_TIME) {
|
||||
win.wyReg.reader3().schedule(win.wxReader.getSource(), scxReader, cycleCounter);
|
||||
m3EventQueue.push(&win.wyReg.reader3());
|
||||
}
|
||||
|
||||
if (weMasterChecker.time() != VideoEvent::DISABLED_TIME) {
|
||||
weMasterChecker.schedule(wyReg.getSource(), we.getSource(), cycleCounter);
|
||||
m3EventQueue.push(&weMasterChecker);
|
||||
if (win.weMasterChecker.time() != VideoEvent::DISABLED_TIME) {
|
||||
win.weMasterChecker.schedule(win.wyReg.getSource(), win.we.getSource(), cycleCounter);
|
||||
m3EventQueue.push(&win.weMasterChecker);
|
||||
}
|
||||
|
||||
if (scReader.time() != VideoEvent::DISABLED_TIME) {
|
||||
@ -588,12 +584,12 @@ void LCD::weChange(const bool newValue, const unsigned long cycleCounter) {
|
||||
update(cycleCounter);
|
||||
// printf("%u: weChange: %u\n", videoCycles, newValue);
|
||||
|
||||
addEvent(weMasterChecker, wyReg.getSource(), newValue, cycleCounter, m3EventQueue);
|
||||
addEvent(win.weMasterChecker, win.wyReg.getSource(), newValue, cycleCounter, m3EventQueue);
|
||||
// addEvent(weMasterChecker, lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
we.setSource(newValue);
|
||||
addEvent(we.disableChecker(), scxReader.scxAnd7(), wxReader.wx(), lyCounter, cycleCounter, m3EventQueue);
|
||||
addEvent(we.enableChecker(), scxReader.scxAnd7(), wxReader.wx(), lyCounter, cycleCounter, m3EventQueue);
|
||||
win.we.setSource(newValue);
|
||||
addEvent(win.we.disableChecker(), scxReader.scxAnd7(), win.wxReader.wx(), lyCounter, cycleCounter, m3EventQueue);
|
||||
addEvent(win.we.enableChecker(), scxReader.scxAnd7(), win.wxReader.wx(), lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
addEvent(mode3Event, vEventQueue);
|
||||
}
|
||||
@ -602,11 +598,11 @@ void LCD::wxChange(const unsigned newValue, const unsigned long cycleCounter) {
|
||||
update(cycleCounter);
|
||||
// printf("%u: wxChange: 0x%X\n", videoCycles, newValue);
|
||||
|
||||
wxReader.setSource(newValue);
|
||||
addEvent(wxReader, scxReader.scxAnd7(), lyCounter, cycleCounter, m3EventQueue);
|
||||
win.wxReader.setSource(newValue);
|
||||
addEvent(win.wxReader, scxReader.scxAnd7(), lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
if (wyReg.reader3().time() != VideoEvent::DISABLED_TIME)
|
||||
addEvent(wyReg.reader3(), wxReader.getSource(), scxReader, cycleCounter, m3EventQueue);
|
||||
if (win.wyReg.reader3().time() != VideoEvent::DISABLED_TIME)
|
||||
addEvent(win.wyReg.reader3(), win.wxReader.getSource(), scxReader, cycleCounter, m3EventQueue);
|
||||
|
||||
addEvent(mode3Event, vEventQueue);
|
||||
}
|
||||
@ -615,13 +611,13 @@ void LCD::wyChange(const unsigned newValue, const unsigned long cycleCounter) {
|
||||
update(cycleCounter);
|
||||
// printf("%u: wyChange: 0x%X\n", videoCycles, newValue);
|
||||
|
||||
wyReg.setSource(newValue);
|
||||
addEvent(wyReg.reader1(), lyCounter, cycleCounter, m3EventQueue);
|
||||
addEvent(wyReg.reader2(), lyCounter, cycleCounter, m3EventQueue);
|
||||
addEvent(wyReg.reader3(), wxReader.getSource(), scxReader, cycleCounter, m3EventQueue);
|
||||
addEvent(wyReg.reader4(), lyCounter, cycleCounter, m3EventQueue);
|
||||
win.wyReg.setSource(newValue);
|
||||
addEvent(win.wyReg.reader1(), lyCounter, cycleCounter, m3EventQueue);
|
||||
addEvent(win.wyReg.reader2(), lyCounter, cycleCounter, m3EventQueue);
|
||||
addEvent(win.wyReg.reader3(), win.wxReader.getSource(), scxReader, cycleCounter, m3EventQueue);
|
||||
addEvent(win.wyReg.reader4(), lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
addEvent(weMasterChecker, newValue, we.getSource(), cycleCounter, m3EventQueue);
|
||||
addEvent(win.weMasterChecker, newValue, win.we.getSource(), cycleCounter, m3EventQueue);
|
||||
|
||||
addEvent(mode3Event, vEventQueue);
|
||||
}
|
||||
@ -633,10 +629,8 @@ void LCD::scxChange(const unsigned newScx, const unsigned long cycleCounter) {
|
||||
scxReader.setSource(newScx);
|
||||
addEvent(scxReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
addEvent(spriteMapper, lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
if (wyReg.reader3().time() != VideoEvent::DISABLED_TIME)
|
||||
addEvent(wyReg.reader3(), wxReader.getSource(), scxReader, cycleCounter, m3EventQueue);
|
||||
if (win.wyReg.reader3().time() != VideoEvent::DISABLED_TIME)
|
||||
addEvent(win.wyReg.reader3(), win.wxReader.getSource(), scxReader, cycleCounter, m3EventQueue);
|
||||
|
||||
addEvent(mode3Event, vEventQueue);
|
||||
|
||||
@ -669,12 +663,8 @@ void LCD::spriteSizeChange(const bool newLarge, const unsigned long cycleCounter
|
||||
update(cycleCounter);
|
||||
//printf("spriteSizeChange\n");
|
||||
|
||||
spriteSizeReader.setSource(newLarge);
|
||||
addEvent(spriteSizeReader, lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
//if (spriteSizeReader.time() < spriteMapper.time()) {
|
||||
// addEvent(spriteMapper, m3EventQueue);
|
||||
//}
|
||||
spriteMapper.setLargeSpritesSource(newLarge);
|
||||
addEvent(spriteMapper, lyCounter, cycleCounter, m3EventQueue);
|
||||
|
||||
addEvent(mode3Event, vEventQueue);
|
||||
}
|
||||
@ -885,15 +875,11 @@ unsigned LCD::get_stat(const unsigned lycReg, const unsigned long cycleCounter)
|
||||
stat = 3;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned lyc;
|
||||
|
||||
if (lycReg)
|
||||
lyc = lyCounter.ly() == lycReg && timeToNextLy > 4U - (doubleSpeed << 2);
|
||||
else
|
||||
lyc = (lyCounter.ly() == 153 && (timeToNextLy >> doubleSpeed) <= 456 - 8) || (lyCounter.ly() == 0 && timeToNextLy > 4U - (doubleSpeed << 2));
|
||||
|
||||
stat |= lyc << 2;
|
||||
if (lyCounter.ly() == lycReg && timeToNextLy > 4U - doubleSpeed * 4U ||
|
||||
lycReg == 0 && lyCounter.ly() == 153 && timeToNextLy >> doubleSpeed <= 456 - 8) {
|
||||
stat |= 4;
|
||||
}
|
||||
}
|
||||
|
||||
return stat;
|
||||
@ -915,7 +901,7 @@ void LCD::do_update(unsigned cycles) {
|
||||
winYPos = 0xFF;
|
||||
//scy[0] = scy[1] = memory.fastread(0xFF42);
|
||||
//scx[0] = scx[1] = memory.fastread(0xFF43);
|
||||
weMasterChecker.unset();
|
||||
win.weMasterChecker.unset();
|
||||
}
|
||||
|
||||
videoCycles += cycles;
|
||||
@ -1003,7 +989,7 @@ void LCD::setDmgPaletteColor(const unsigned palNum, const unsigned colorNum, con
|
||||
}
|
||||
|
||||
void LCD::null_draw(unsigned /*xpos*/, const unsigned ypos, const unsigned endX) {
|
||||
const bool enableWindow = we.value() && wxReader.wx() < 0xA7 && ypos >= wyReg.value() && (weMasterChecker.weMaster() || ypos == wyReg.value());
|
||||
const bool enableWindow = win.enabled(ypos);
|
||||
|
||||
if (enableWindow && winYPos == 0xFF)
|
||||
winYPos = /*ypos - wyReg.value()*/ 0;
|
||||
@ -1018,24 +1004,24 @@ template<typename T>
|
||||
void LCD::cgb_draw(unsigned xpos, const unsigned ypos, const unsigned endX) {
|
||||
const unsigned effectiveScx = scReader.scx();
|
||||
|
||||
const bool enableWindow = we.value() && wxReader.wx() < 0xA7 && ypos >= wyReg.value() && (weMasterChecker.weMaster() || ypos == wyReg.value());
|
||||
const bool enableWindow = win.enabled(ypos);
|
||||
|
||||
if (enableWindow && winYPos == 0xFF)
|
||||
winYPos = /*ypos - wyReg.value()*/ 0;
|
||||
|
||||
T *const bufLine = static_cast<T*>(dbuffer) + ypos * static_cast<unsigned long>(dpitch);
|
||||
|
||||
if (!(enableWindow && wxReader.wx() <= xpos + 7)) {
|
||||
if (!(enableWindow && win.wxReader.wx() <= xpos + 7)) {
|
||||
const unsigned fby = scReader.scy() + ypos /*& 0xFF*/;
|
||||
const unsigned end = std::min(enableWindow ? wxReader.wx() - 7 : 160U, endX);
|
||||
const unsigned end = std::min(enableWindow ? win.wxReader.wx() - 7 : 160U, endX);
|
||||
|
||||
cgb_bg_drawPixels(bufLine, xpos, end, effectiveScx, bgTileMap + (fby & 0xF8) * 4, bgTileData, fby & 7);
|
||||
}
|
||||
|
||||
if (enableWindow && endX + 7 > wxReader.wx()) {
|
||||
const unsigned start = std::max(wxReader.wx() < 7 ? 0U : (wxReader.wx() - 7), xpos);
|
||||
if (enableWindow && endX + 7 > win.wxReader.wx()) {
|
||||
const unsigned start = std::max(win.wxReader.wx() < 7 ? 0U : (win.wxReader.wx() - 7), xpos);
|
||||
|
||||
cgb_bg_drawPixels(bufLine, start, endX, 7u - wxReader.wx(), wdTileMap + (winYPos & 0xF8) * 4, bgTileData, winYPos & 7);
|
||||
cgb_bg_drawPixels(bufLine, start, endX, 7u - win.wxReader.wx(), wdTileMap + (winYPos & 0xF8) * 4, bgTileData, winYPos & 7);
|
||||
}
|
||||
|
||||
if (endX == 160) {
|
||||
@ -1051,7 +1037,7 @@ template<typename T>
|
||||
void LCD::dmg_draw(unsigned xpos, const unsigned ypos, const unsigned endX) {
|
||||
const unsigned effectiveScx = scReader.scx();
|
||||
|
||||
const bool enableWindow = we.value() && wxReader.wx() < 0xA7 && ypos >= wyReg.value() && (weMasterChecker.weMaster() || ypos == wyReg.value());
|
||||
const bool enableWindow = win.enabled(ypos);
|
||||
|
||||
if (enableWindow && winYPos == 0xFF)
|
||||
winYPos = /*ypos - wyReg.value()*/ 0;
|
||||
@ -1059,17 +1045,17 @@ void LCD::dmg_draw(unsigned xpos, const unsigned ypos, const unsigned endX) {
|
||||
T *const bufLine = static_cast<T*>(dbuffer) + ypos * static_cast<unsigned long>(dpitch);
|
||||
|
||||
if (bgEnable) {
|
||||
if (!(enableWindow && wxReader.wx() <= xpos + 7)) {
|
||||
if (!(enableWindow && win.wxReader.wx() <= xpos + 7)) {
|
||||
const unsigned fby = scReader.scy() + ypos /*& 0xFF*/;
|
||||
const unsigned end = std::min(enableWindow ? wxReader.wx() - 7 : 160U, endX);
|
||||
const unsigned end = std::min(enableWindow ? win.wxReader.wx() - 7 : 160U, endX);
|
||||
|
||||
bg_drawPixels(bufLine, xpos, end, effectiveScx, bgTileMap + (fby & 0xF8) * 4, bgTileData + (fby & 7) * 2);
|
||||
}
|
||||
|
||||
if (enableWindow && endX + 7 > wxReader.wx()) {
|
||||
const unsigned start = std::max(wxReader.wx() < 7 ? 0U : (wxReader.wx() - 7), xpos);
|
||||
if (enableWindow && endX + 7 > win.wxReader.wx()) {
|
||||
const unsigned start = std::max(win.wxReader.wx() < 7 ? 0U : (win.wxReader.wx() - 7), xpos);
|
||||
|
||||
bg_drawPixels(bufLine, start, endX, 7u - wxReader.wx(), wdTileMap + (winYPos & 0xF8) * 4, bgTileData + (winYPos & 7) * 2);
|
||||
bg_drawPixels(bufLine, start, endX, 7u - win.wxReader.wx(), wdTileMap + (winYPos & 0xF8) * 4, bgTileData + (winYPos & 7) * 2);
|
||||
}
|
||||
} else
|
||||
std::fill_n(bufLine + xpos, endX - xpos, bgPalette[0]);
|
||||
@ -1256,13 +1242,12 @@ static unsigned cgb_toplayerBG_mask(const unsigned spx, const unsigned bgStart,
|
||||
template<typename T>
|
||||
void LCD::cgb_drawSprites(T * const buffer_line, const unsigned ypos) {
|
||||
const unsigned scy = scReader.scy() + ypos /*& 0xFF*/;
|
||||
const unsigned wx = wxReader.wx() < 7 ? 0 : wxReader.wx() - 7;
|
||||
//const bool enableWindow = (memory.fastread(0xFF40) & 0x20) && (ypos >= memory.fastread(0xFF4A)) && (wx < 160);
|
||||
const bool enableWindow = we.value() && wxReader.wx() < 0xA7 && ypos >= wyReg.value() && (weMasterChecker.weMaster() || ypos == wyReg.value());
|
||||
const unsigned short *const spriteMapLine = spriteMapper.sprites(ypos);
|
||||
const unsigned wx = win.wxReader.wx() < 7 ? 0 : win.wxReader.wx() - 7;
|
||||
const bool enableWindow = win.enabled(ypos);
|
||||
const unsigned char *const spriteMapLine = spriteMapper.sprites(ypos);
|
||||
|
||||
for (int i = spriteMapper.numSprites(ypos) - 1; i >= 0; --i) {
|
||||
const unsigned char *const spriteInfo = spriteMapper.oamram + (spriteMapLine[i] & 0xFF);
|
||||
const unsigned char *const spriteInfo = spriteMapper.oamram + spriteMapLine[i];
|
||||
const unsigned spx = spriteInfo[1];
|
||||
|
||||
if (spx < 168 && spx) {
|
||||
@ -1270,7 +1255,7 @@ void LCD::cgb_drawSprites(T * const buffer_line, const unsigned ypos) {
|
||||
unsigned spTile = spriteInfo[2];
|
||||
const unsigned attributes = spriteInfo[3];
|
||||
|
||||
if (spriteSizeReader.largeSprites()) {
|
||||
if (spriteMapper.largeSprites()) {
|
||||
if (attributes & 0x40) //yflip
|
||||
spLine = 15 - spLine;
|
||||
|
||||
@ -1430,12 +1415,12 @@ static unsigned prioritizedBG_mask(const unsigned spx, const unsigned bgStart, c
|
||||
template<typename T>
|
||||
void LCD::drawSprites(T * const buffer_line, const unsigned ypos) {
|
||||
const unsigned scy = scReader.scy() + ypos /*& 0xFF*/;
|
||||
const unsigned wx = wxReader.wx() < 7 ? 0 : wxReader.wx() - 7;
|
||||
const bool enableWindow = we.value() && wxReader.wx() < 0xA7 && ypos >= wyReg.value() && (weMasterChecker.weMaster() || ypos == wyReg.value());
|
||||
const unsigned short *const spriteMapLine = spriteMapper.sprites(ypos);
|
||||
const unsigned wx = win.wxReader.wx() < 7 ? 0 : win.wxReader.wx() - 7;
|
||||
const bool enableWindow = win.enabled(ypos);
|
||||
const unsigned char *const spriteMapLine = spriteMapper.sprites(ypos);
|
||||
|
||||
for (int i = spriteMapper.numSprites(ypos) - 1; i >= 0; --i) {
|
||||
const unsigned char *const spriteInfo = spriteMapper.oamram + (spriteMapLine[i] & 0xFF);
|
||||
const unsigned char *const spriteInfo = spriteMapper.oamram + spriteMapLine[i];
|
||||
const unsigned spx = spriteInfo[1];
|
||||
|
||||
if (spx < 168 && spx) {
|
||||
@ -1443,7 +1428,7 @@ void LCD::drawSprites(T * const buffer_line, const unsigned ypos) {
|
||||
unsigned spTile = spriteInfo[2];
|
||||
const unsigned attributes = spriteInfo[3];
|
||||
|
||||
if (spriteSizeReader.largeSprites()) {
|
||||
if (spriteMapper.largeSprites()) {
|
||||
if (attributes & 0x40) //yflip
|
||||
spLine = 15 - spLine;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -32,11 +32,7 @@ class Filter;
|
||||
|
||||
#include "video/video_event_comparer.h"
|
||||
#include "video/ly_counter.h"
|
||||
#include "video/sprite_size_reader.h"
|
||||
#include "video/wx_reader.h"
|
||||
#include "video/wy.h"
|
||||
#include "video/we.h"
|
||||
#include "video/we_master_checker.h"
|
||||
#include "video/window.h"
|
||||
#include "video/scx_reader.h"
|
||||
#include "video/sprite_mapper.h"
|
||||
#include "video/sc_reader.h"
|
||||
@ -51,8 +47,6 @@ class Filter;
|
||||
#include "video/m3_extra_cycles.h"
|
||||
|
||||
class LCD {
|
||||
friend class M3ExtraCycles;
|
||||
|
||||
//static const uint8_t xflipt[0x100];
|
||||
unsigned long dmgColorsRgb32[3 * 4];
|
||||
unsigned long dmgColorsRgb16[3 * 4];
|
||||
@ -85,16 +79,11 @@ class LCD {
|
||||
event_queue<VideoEvent*,VideoEventComparer> irqEventQueue;
|
||||
event_queue<VideoEvent*,VideoEventComparer> vEventQueue;
|
||||
|
||||
const M3ExtraCycles m3ExtraCycles;
|
||||
|
||||
LyCounter lyCounter;
|
||||
We we;
|
||||
WeMasterChecker weMasterChecker;
|
||||
Wy wyReg;
|
||||
WxReader wxReader;
|
||||
SpriteSizeReader spriteSizeReader;
|
||||
Window win;
|
||||
ScxReader scxReader;
|
||||
SpriteMapper spriteMapper;
|
||||
M3ExtraCycles m3ExtraCycles;
|
||||
ScReader scReader;
|
||||
BreakEvent breakEvent;
|
||||
Mode3Event mode3Event;
|
||||
|
@ -17,20 +17,85 @@
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "m3_extra_cycles.h"
|
||||
#include "scx_reader.h"
|
||||
#include "window.h"
|
||||
#include "sprite_mapper.h"
|
||||
#include "../insertion_sort.h"
|
||||
|
||||
#include "../video.h"
|
||||
|
||||
M3ExtraCycles::M3ExtraCycles(const LCD &video) :
|
||||
video(video)
|
||||
{}
|
||||
|
||||
unsigned M3ExtraCycles::operator()(const unsigned ly) const {
|
||||
unsigned cycles = video.spriteMapper.spriteCycles(ly);
|
||||
|
||||
cycles += video.scxReader.scxAnd7();
|
||||
|
||||
if (video.we.value() && video.wxReader.wx() < 0xA7 && ly >= video.wyReg.value() && (video.weMasterChecker.weMaster() || ly == video.wyReg.value()))
|
||||
cycles += 6;
|
||||
|
||||
return cycles;
|
||||
M3ExtraCycles::M3ExtraCycles(const SpriteMapper &spriteMapper,
|
||||
const ScxReader &scxReader,
|
||||
const Window &win) :
|
||||
spriteMapper(spriteMapper),
|
||||
scxReader(scxReader),
|
||||
win(win)
|
||||
{
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
static const unsigned char* addLineCycles(const unsigned char *const start, const unsigned char *const end,
|
||||
const unsigned maxSpx, const unsigned scwxAnd7, const unsigned char *const oamram_plus1, unsigned char *cycles_out) {
|
||||
unsigned sum = 0;
|
||||
|
||||
const unsigned char *a = start;
|
||||
|
||||
for (; a < end; ++a) {
|
||||
const unsigned spx = oamram_plus1[*a];
|
||||
|
||||
if (spx > maxSpx)
|
||||
break;
|
||||
|
||||
unsigned cycles = 6;
|
||||
const unsigned posAnd7 = scwxAnd7 + spx & 7;
|
||||
|
||||
if (posAnd7 < 5) {
|
||||
cycles = 11 - posAnd7;
|
||||
|
||||
for (const unsigned char *b = a; b > start;) {
|
||||
const unsigned bSpx = oamram_plus1[*--b];
|
||||
|
||||
if (spx - bSpx > 4U)
|
||||
break;
|
||||
|
||||
if ((scwxAnd7 + bSpx & 7) < 4 || spx == bSpx) {
|
||||
cycles = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sum += cycles;
|
||||
}
|
||||
|
||||
*cycles_out += sum;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
void M3ExtraCycles::updateLine(const unsigned ly) const {
|
||||
const bool windowEnabled = win.enabled(ly);
|
||||
|
||||
cycles[ly] = windowEnabled ? scxReader.scxAnd7() + 6 : scxReader.scxAnd7();
|
||||
|
||||
const unsigned numSprites = spriteMapper.numSprites(ly);
|
||||
|
||||
if (numSprites == 0)
|
||||
return;
|
||||
|
||||
unsigned char sortBuf[10];
|
||||
const unsigned char *tmp = spriteMapper.sprites(ly);
|
||||
|
||||
if (spriteMapper.isCgb()) {
|
||||
std::memcpy(sortBuf, tmp, sizeof(sortBuf));
|
||||
insertionSort(sortBuf, sortBuf + numSprites);
|
||||
tmp = sortBuf;
|
||||
}
|
||||
|
||||
const unsigned char *const tmpend = tmp + numSprites;
|
||||
const unsigned char *const oamram_plus1 = spriteMapper.oamram + 1;
|
||||
|
||||
if (windowEnabled) {
|
||||
addLineCycles(addLineCycles(tmp, tmpend, win.wxReader.wx(), scxReader.scxAnd7(), oamram_plus1, cycles + ly),
|
||||
tmpend, 167, 7 - win.wxReader.wx(), oamram_plus1, cycles + ly);
|
||||
} else
|
||||
addLineCycles(tmp, tmpend, 167, scxReader.scxAnd7(), oamram_plus1, cycles + ly);
|
||||
}
|
||||
|
@ -19,14 +19,38 @@
|
||||
#ifndef VIDEO_M3_EXTRA_CYCLES_H
|
||||
#define VIDEO_M3_EXTRA_CYCLES_H
|
||||
|
||||
class LCD;
|
||||
class ScxReader;
|
||||
class Window;
|
||||
class SpriteMapper;
|
||||
|
||||
#include <cstring>
|
||||
|
||||
class M3ExtraCycles {
|
||||
const LCD &video;
|
||||
enum { CYCLES_INVALID = 0xFF };
|
||||
|
||||
mutable unsigned char cycles[144];
|
||||
|
||||
const SpriteMapper &spriteMapper;
|
||||
const ScxReader &scxReader;
|
||||
const Window &win;
|
||||
|
||||
void updateLine(unsigned ly) const;
|
||||
|
||||
public:
|
||||
M3ExtraCycles(const LCD &video);
|
||||
unsigned operator()(unsigned ly) const;
|
||||
M3ExtraCycles(const SpriteMapper &spriteMapper,
|
||||
const ScxReader &scxReader_in,
|
||||
const Window &win);
|
||||
|
||||
void invalidateCache() {
|
||||
std::memset(cycles, CYCLES_INVALID, sizeof(cycles));
|
||||
}
|
||||
|
||||
unsigned operator()(const unsigned ly) const {
|
||||
if (cycles[ly] == CYCLES_INVALID)
|
||||
updateLine(ly);
|
||||
|
||||
return cycles[ly];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -19,18 +19,21 @@
|
||||
#include "scx_reader.h"
|
||||
|
||||
#include "../event_queue.h"
|
||||
#include "m3_extra_cycles.h"
|
||||
|
||||
ScxReader::ScxReader(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue_in,
|
||||
// VideoEvent &wyReader3_in,
|
||||
VideoEvent &wxReader_in,
|
||||
VideoEvent &weEnableChecker_in,
|
||||
VideoEvent &weDisableChecker_in) :
|
||||
VideoEvent &weDisableChecker_in,
|
||||
M3ExtraCycles &m3ExtraCycles) :
|
||||
VideoEvent(1),
|
||||
m3EventQueue(m3EventQueue_in),
|
||||
// wyReader3(wyReader3_in),
|
||||
wxReader(wxReader_in),
|
||||
weEnableChecker(weEnableChecker_in),
|
||||
weDisableChecker(weDisableChecker_in)
|
||||
weDisableChecker(weDisableChecker_in),
|
||||
m3ExtraCycles(m3ExtraCycles)
|
||||
{
|
||||
setDoubleSpeed(false);
|
||||
setSource(0);
|
||||
@ -53,5 +56,7 @@ void ScxReader::doEvent() {
|
||||
rescheduleEvent(weEnableChecker, diff);
|
||||
rescheduleEvent(weDisableChecker, diff);
|
||||
|
||||
m3ExtraCycles.invalidateCache();
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -20,6 +20,7 @@
|
||||
#define SCX_READER_H
|
||||
|
||||
template<typename T, class Comparer> class event_queue;
|
||||
class M3ExtraCycles;
|
||||
|
||||
#include "video_event.h"
|
||||
#include "video_event_comparer.h"
|
||||
@ -31,6 +32,7 @@ class ScxReader : public VideoEvent {
|
||||
VideoEvent &wxReader;
|
||||
VideoEvent &weEnableChecker;
|
||||
VideoEvent &weDisableChecker;
|
||||
M3ExtraCycles &m3ExtraCycles;
|
||||
|
||||
unsigned char scxAnd7_;
|
||||
unsigned char src;
|
||||
@ -43,7 +45,8 @@ public:
|
||||
// VideoEvent &wyReader3_in,
|
||||
VideoEvent &wxReader_in,
|
||||
VideoEvent &weEnableChecker_in,
|
||||
VideoEvent &weDisableChecker_in);
|
||||
VideoEvent &weDisableChecker_in,
|
||||
M3ExtraCycles &m3ExtraCycles);
|
||||
|
||||
void doEvent();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -17,35 +17,43 @@
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "sprite_mapper.h"
|
||||
#include "sprite_size_reader.h"
|
||||
#include "scx_reader.h"
|
||||
#include "../event_queue.h"
|
||||
|
||||
// #include <algorithm>
|
||||
#include "m3_extra_cycles.h"
|
||||
#include "../insertion_sort.h"
|
||||
#include <cstring>
|
||||
|
||||
SpriteMapper::SpriteMapper(const SpriteSizeReader &spriteSizeReader_in,
|
||||
const ScxReader &scxReader_in,
|
||||
const unsigned char *const oamram_in) :
|
||||
// #include <algorithm>
|
||||
|
||||
class SpxLess {
|
||||
const unsigned char *const oamram_plus1;
|
||||
|
||||
public:
|
||||
SpxLess(const unsigned char *const oamram) : oamram_plus1(oamram + 1) {}
|
||||
|
||||
bool operator()(const unsigned char l, const unsigned char r) const {
|
||||
return oamram_plus1[l] < oamram_plus1[r];
|
||||
}
|
||||
};
|
||||
|
||||
SpriteMapper::SpriteMapper(M3ExtraCycles &m3ExtraCycles,
|
||||
const unsigned char *const oamram) :
|
||||
VideoEvent(2),
|
||||
spriteSizeReader(spriteSizeReader_in),
|
||||
scxReader(scxReader_in),
|
||||
oamram(oamram_in)
|
||||
m3ExtraCycles(m3ExtraCycles),
|
||||
oamram(oamram)
|
||||
{
|
||||
setDoubleSpeed(false);
|
||||
setCgb(false);
|
||||
setLargeSpritesSource(false);
|
||||
largeSprites_ = largeSpritesSrc_;
|
||||
clearMap();
|
||||
}
|
||||
|
||||
void SpriteMapper::clearMap() {
|
||||
std::memset(cycles, CYCLES_INVALID, sizeof(cycles));
|
||||
std::memset(num, 0, sizeof(num));
|
||||
std::memset(num, cgb ? 0 : NEED_SORTING_MASK, sizeof(num));
|
||||
}
|
||||
|
||||
void SpriteMapper::mapSprites() {
|
||||
clearMap();
|
||||
|
||||
const unsigned spriteHeight = 8u << spriteSizeReader.largeSprites();
|
||||
const unsigned spriteHeight = 8u << largeSprites();
|
||||
|
||||
for (unsigned i = 0x00; i < 0xA0; i += 4) {
|
||||
const unsigned bottom_pos = oamram[i] - (17u - spriteHeight);
|
||||
@ -53,10 +61,7 @@ void SpriteMapper::mapSprites() {
|
||||
if (bottom_pos >= 143 + spriteHeight)
|
||||
continue;
|
||||
|
||||
const unsigned spx = oamram[i + 1];
|
||||
const unsigned value = spx << 8 | i;
|
||||
|
||||
unsigned short *map = spritemap;
|
||||
unsigned char *map = spritemap;
|
||||
unsigned char *n = num;
|
||||
|
||||
if (bottom_pos >= spriteHeight) {
|
||||
@ -68,95 +73,30 @@ void SpriteMapper::mapSprites() {
|
||||
unsigned char *const end = num + (bottom_pos >= 143 ? 143 : bottom_pos);
|
||||
|
||||
do {
|
||||
if (*n < 10)
|
||||
map[(*n)++] = value;
|
||||
if ((*n & ~NEED_SORTING_MASK) < 10)
|
||||
map[(*n)++ & ~NEED_SORTING_MASK] = i;
|
||||
|
||||
map += 10;
|
||||
++n;
|
||||
} while (n <= end);
|
||||
}
|
||||
|
||||
m3ExtraCycles.invalidateCache();
|
||||
}
|
||||
|
||||
// unsafe if start is at the end of allocated memory, since start+1 could be undefined/of.
|
||||
static void insertionSort(unsigned short *const start, unsigned short *const end) {
|
||||
unsigned short *a = start;
|
||||
|
||||
while (++a < end) {
|
||||
const unsigned e = *a;
|
||||
|
||||
unsigned short *b = a;
|
||||
|
||||
while (b != start && *(b - 1) > e) {
|
||||
*b = *(b - 1);
|
||||
b = b - 1;
|
||||
}
|
||||
|
||||
*b = e;
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteMapper::updateLine(const unsigned ly) const {
|
||||
if (num[ly] == 0) {
|
||||
cycles[ly] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned short sortBuf[10];
|
||||
unsigned short *tmp = spritemap + ly * 10;
|
||||
|
||||
if (cgb) {
|
||||
std::memcpy(sortBuf, tmp, sizeof(sortBuf));
|
||||
tmp = sortBuf;
|
||||
}
|
||||
|
||||
insertionSort(tmp, tmp + num[ly]);
|
||||
// std::sort(tmp, tmp + num[ly]);
|
||||
|
||||
unsigned sum = 0;
|
||||
|
||||
for (unsigned i = 0; i < num[ly]; ++i) {
|
||||
const unsigned spx = tmp[i] >> 8;
|
||||
|
||||
if (spx > 167)
|
||||
break;
|
||||
|
||||
unsigned cycles = 6;
|
||||
const unsigned posAnd7 = scxReader.scxAnd7() + spx & 7;
|
||||
|
||||
if (posAnd7 < 5) {
|
||||
cycles = 11 - posAnd7;
|
||||
|
||||
for (unsigned j = i; j--;) {
|
||||
const unsigned tmpSpx = tmp[j] >> 8;
|
||||
|
||||
if (spx - tmpSpx > 4U)
|
||||
break;
|
||||
|
||||
if ((scxReader.scxAnd7() + tmpSpx & 7) < 4 || spx == tmpSpx) {
|
||||
cycles = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sum += cycles;
|
||||
}
|
||||
|
||||
cycles[ly] = sum;
|
||||
void SpriteMapper::sortLine(const unsigned ly) const {
|
||||
num[ly] &= ~NEED_SORTING_MASK;
|
||||
insertionSort(spritemap + ly * 10, spritemap + ly * 10 + num[ly], SpxLess(oamram));
|
||||
}
|
||||
|
||||
void SpriteMapper::doEvent() {
|
||||
largeSprites_ = largeSpritesSrc_;
|
||||
mapSprites();
|
||||
|
||||
if (spriteSizeReader.time() < scxReader.time())
|
||||
setTime(spriteSizeReader.time() + timeDiff);
|
||||
else
|
||||
setTime(scxReader.time());
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
void SpriteMapper::reset() {
|
||||
mapSprites();
|
||||
setTime(DISABLED_TIME);
|
||||
doEvent();
|
||||
}
|
||||
|
||||
/*void SpriteMapper::schedule() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -23,67 +23,63 @@
|
||||
//#include "video_event_comparer.h"
|
||||
#include "ly_counter.h"
|
||||
|
||||
template<typename T, class Comparer> class event_queue;
|
||||
class SpriteSizeReader;
|
||||
class ScxReader;
|
||||
class M3ExtraCycles;
|
||||
|
||||
class SpriteMapper : public VideoEvent {
|
||||
enum { CYCLES_INVALID = 0xFF };
|
||||
enum { NEED_SORTING_MASK = 0x80 };
|
||||
|
||||
mutable unsigned short spritemap[144*10];
|
||||
mutable unsigned char cycles[144];
|
||||
unsigned char num[144];
|
||||
mutable unsigned char spritemap[144*10];
|
||||
mutable unsigned char num[144];
|
||||
|
||||
const SpriteSizeReader &spriteSizeReader;
|
||||
const ScxReader &scxReader;
|
||||
M3ExtraCycles &m3ExtraCycles;
|
||||
|
||||
public:
|
||||
const unsigned char *const oamram;
|
||||
|
||||
private:
|
||||
unsigned char timeDiff;
|
||||
bool largeSprites_;
|
||||
bool largeSpritesSrc_;
|
||||
bool cgb;
|
||||
|
||||
void clearMap();
|
||||
void mapSprites();
|
||||
void updateLine(unsigned ly) const;
|
||||
void sortLine(unsigned ly) const;
|
||||
|
||||
public:
|
||||
SpriteMapper(const SpriteSizeReader &spriteSizeReader_in,
|
||||
const ScxReader &scxReader_in,
|
||||
SpriteMapper(M3ExtraCycles &m3ExtraCycles,
|
||||
const unsigned char *const oamram_in);
|
||||
|
||||
void doEvent();
|
||||
|
||||
bool isCgb() const {
|
||||
return cgb;
|
||||
}
|
||||
|
||||
bool largeSprites() const {
|
||||
return largeSprites_;
|
||||
}
|
||||
|
||||
unsigned numSprites(const unsigned ly) const {
|
||||
return num[ly] & ~NEED_SORTING_MASK;
|
||||
}
|
||||
|
||||
void reset();
|
||||
|
||||
void schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) {
|
||||
// synced to scxReader.
|
||||
setTime(lyCounter.nextLineCycle(82 + lyCounter.isDoubleSpeed() * 3, cycleCounter));
|
||||
setTime(lyCounter.nextLineCycle(16 + lyCounter.isDoubleSpeed() * 4, cycleCounter));
|
||||
}
|
||||
|
||||
void setCgb(const bool cgb_in) {
|
||||
cgb = cgb_in;
|
||||
}
|
||||
|
||||
void setDoubleSpeed(const bool dS) {
|
||||
timeDiff = dS ? 85 * 2 - 40 : (82 - 16);
|
||||
void setLargeSpritesSource(const bool src) {
|
||||
largeSpritesSrc_ = src;
|
||||
}
|
||||
|
||||
unsigned numSprites(const unsigned ly) const {
|
||||
return num[ly];
|
||||
}
|
||||
|
||||
unsigned spriteCycles(const unsigned ly) const {
|
||||
if (cycles[ly] == CYCLES_INVALID)
|
||||
updateLine(ly);
|
||||
|
||||
return cycles[ly];
|
||||
}
|
||||
|
||||
const unsigned short* sprites(const unsigned ly) const {
|
||||
if (cycles[ly] == CYCLES_INVALID)
|
||||
updateLine(ly);
|
||||
const unsigned char* sprites(const unsigned ly) const {
|
||||
if (num[ly] & NEED_SORTING_MASK)
|
||||
sortLine(ly);
|
||||
|
||||
return spritemap + ly * 10;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
static const unsigned long DISABLED_TIME = 0xFFFFFFFF;
|
||||
|
||||
VideoEvent(const unsigned priority_in) :
|
||||
time_(DISABLED_TIME),
|
||||
priority_(priority_in)
|
||||
{}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -18,36 +18,35 @@
|
||||
***************************************************************************/
|
||||
#include "we.h"
|
||||
|
||||
We::WeEnableChecker::WeEnableChecker(bool &we_in, const bool &src_in) :
|
||||
We::WeEnableChecker::WeEnableChecker(We &we) :
|
||||
VideoEvent(8),
|
||||
we(we_in),
|
||||
src(src_in)
|
||||
we(we)
|
||||
{}
|
||||
|
||||
void We::WeEnableChecker::doEvent() {
|
||||
we = src;
|
||||
we.set(we.src_);
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
We::WeDisableChecker::WeDisableChecker(bool &we_in, const bool &src_in) :
|
||||
We::WeDisableChecker::WeDisableChecker(We &we) :
|
||||
VideoEvent(9),
|
||||
we(we_in),
|
||||
src(src_in)
|
||||
we(we)
|
||||
{}
|
||||
|
||||
void We::WeDisableChecker::doEvent() {
|
||||
we = we && src;
|
||||
we.set(we.we_ & we.src_);
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
We::We() :
|
||||
enableChecker_(we_, src_),
|
||||
disableChecker_(we_, src_)
|
||||
We::We(M3ExtraCycles &m3ExtraCycles) :
|
||||
m3ExtraCycles_(m3ExtraCycles),
|
||||
enableChecker_(*this),
|
||||
disableChecker_(*this)
|
||||
{
|
||||
setSource(false);
|
||||
reset();
|
||||
we_ = src_;
|
||||
}
|
||||
|
||||
void We::reset() {
|
||||
|
@ -21,14 +21,14 @@
|
||||
|
||||
#include "video_event.h"
|
||||
#include "ly_counter.h"
|
||||
#include "m3_extra_cycles.h"
|
||||
|
||||
class We {
|
||||
class WeEnableChecker : public VideoEvent {
|
||||
bool &we;
|
||||
const bool &src;
|
||||
We &we;
|
||||
|
||||
public:
|
||||
WeEnableChecker(bool &we_in, const bool &src_in);
|
||||
WeEnableChecker(We &we);
|
||||
|
||||
void doEvent();
|
||||
|
||||
@ -38,11 +38,10 @@ class We {
|
||||
};
|
||||
|
||||
class WeDisableChecker : public VideoEvent {
|
||||
bool &we;
|
||||
const bool &src;
|
||||
We &we;
|
||||
|
||||
public:
|
||||
WeDisableChecker(bool &we_in, const bool &src_in);
|
||||
WeDisableChecker(We &we);
|
||||
|
||||
void doEvent();
|
||||
|
||||
@ -51,15 +50,25 @@ class We {
|
||||
}
|
||||
};
|
||||
|
||||
friend class WeEnableChecker;
|
||||
friend class WeDisableChecker;
|
||||
|
||||
M3ExtraCycles &m3ExtraCycles_;
|
||||
WeEnableChecker enableChecker_;
|
||||
WeDisableChecker disableChecker_;
|
||||
|
||||
bool we_;
|
||||
bool src_;
|
||||
|
||||
void set(const bool value) {
|
||||
if (we_ != value)
|
||||
m3ExtraCycles_.invalidateCache();
|
||||
|
||||
we_ = value;
|
||||
}
|
||||
|
||||
public:
|
||||
We();
|
||||
We(M3ExtraCycles &m3ExtraCycles);
|
||||
|
||||
WeDisableChecker& disableChecker() {
|
||||
return disableChecker_;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -24,13 +24,15 @@
|
||||
|
||||
WeMasterChecker::WeMasterChecker(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue_in,
|
||||
Wy &wy_in,
|
||||
const LyCounter &lyCounter_in) :
|
||||
const LyCounter &lyCounter_in,
|
||||
M3ExtraCycles &m3ExtraCycles) :
|
||||
VideoEvent(10),
|
||||
m3EventQueue(m3EventQueue_in),
|
||||
wy(wy_in),
|
||||
lyCounter(lyCounter_in)
|
||||
lyCounter(lyCounter_in),
|
||||
m3ExtraCycles(m3ExtraCycles)
|
||||
{
|
||||
reset();
|
||||
weMaster_ = false;
|
||||
}
|
||||
|
||||
void WeMasterChecker::doEvent() {
|
||||
@ -40,7 +42,7 @@ void WeMasterChecker::doEvent() {
|
||||
addEvent(wy.reader4(), lyCounter, time(), m3EventQueue);
|
||||
}
|
||||
|
||||
weMaster_ |= true;
|
||||
set(true);
|
||||
// }
|
||||
|
||||
setTime(time() + (70224U << lyCounter.isDoubleSpeed()));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -25,18 +25,28 @@ class Wy;
|
||||
#include "video_event.h"
|
||||
#include "video_event_comparer.h"
|
||||
#include "ly_counter.h"
|
||||
#include "m3_extra_cycles.h"
|
||||
|
||||
class WeMasterChecker : public VideoEvent {
|
||||
event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue;
|
||||
Wy &wy;
|
||||
const LyCounter &lyCounter;
|
||||
M3ExtraCycles &m3ExtraCycles;
|
||||
|
||||
bool weMaster_;
|
||||
|
||||
void set(const bool value) {
|
||||
if (weMaster_ != value)
|
||||
m3ExtraCycles.invalidateCache();
|
||||
|
||||
weMaster_ = value;
|
||||
}
|
||||
|
||||
public:
|
||||
WeMasterChecker(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue_in,
|
||||
Wy &wy_in,
|
||||
const LyCounter &lyCounter_in);
|
||||
const LyCounter &lyCounter_in,
|
||||
M3ExtraCycles &m3ExtraCycles);
|
||||
|
||||
void doEvent();
|
||||
|
||||
@ -53,7 +63,7 @@ public:
|
||||
}
|
||||
|
||||
void unset() {
|
||||
weMaster_ = false;
|
||||
set(false);
|
||||
}
|
||||
|
||||
bool weMaster() const {
|
||||
|
@ -1,61 +1,47 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License version 2 as *
|
||||
* published by the Free Software Foundation. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License version 2 for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* version 2 along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef SPRITE_SIZE_READER_H
|
||||
#define SPRITE_SIZE_READER_H
|
||||
|
||||
template<typename T, class Comparer> class event_queue;
|
||||
class SpriteMapper;
|
||||
|
||||
#include "video_event.h"
|
||||
#include "ly_counter.h"
|
||||
#include "video_event_comparer.h"
|
||||
|
||||
class SpriteSizeReader : public VideoEvent {
|
||||
event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue;
|
||||
SpriteMapper &spriteMapper;
|
||||
const LyCounter &lyCounter;
|
||||
|
||||
bool largeSprites_;
|
||||
bool src_;
|
||||
|
||||
public:
|
||||
SpriteSizeReader(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue_in,
|
||||
SpriteMapper &spriteMapper_in, const LyCounter &lyCounter_in);
|
||||
|
||||
void doEvent();
|
||||
|
||||
bool largeSprites() const {
|
||||
return largeSprites_;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
largeSprites_ = src_;
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
void setSource(const bool src) {
|
||||
src_ = src;
|
||||
}
|
||||
|
||||
void schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) {
|
||||
setTime(lyCounter.nextLineCycle(16 + lyCounter.isDoubleSpeed() * 4, cycleCounter));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License version 2 as *
|
||||
* published by the Free Software Foundation. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License version 2 for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* version 2 along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include "we.h"
|
||||
#include "we_master_checker.h"
|
||||
#include "wy.h"
|
||||
#include "wx_reader.h"
|
||||
|
||||
struct Window {
|
||||
We we;
|
||||
WeMasterChecker weMasterChecker;
|
||||
Wy wyReg;
|
||||
WxReader wxReader;
|
||||
|
||||
Window(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue,
|
||||
const LyCounter &lyCounter,
|
||||
M3ExtraCycles &m3ExtraCycles) :
|
||||
we(m3ExtraCycles),
|
||||
weMasterChecker(m3EventQueue, wyReg, lyCounter, m3ExtraCycles),
|
||||
wyReg(lyCounter, weMasterChecker, m3ExtraCycles),
|
||||
wxReader(m3EventQueue, we.enableChecker(), we.disableChecker(), m3ExtraCycles)
|
||||
{}
|
||||
|
||||
bool enabled(const unsigned ly) const {
|
||||
return we.value() && wxReader.wx() < 0xA7 && ly >= wyReg.value() && (weMasterChecker.weMaster() || ly == wyReg.value());
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*WINDOW_H*/
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -19,14 +19,17 @@
|
||||
#include "wx_reader.h"
|
||||
|
||||
#include "../event_queue.h"
|
||||
#include "m3_extra_cycles.h"
|
||||
|
||||
WxReader::WxReader(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue_in,
|
||||
VideoEvent &weEnableChecker_in,
|
||||
VideoEvent &weDisableChecker_in) :
|
||||
WxReader::WxReader(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue,
|
||||
VideoEvent &weEnableChecker,
|
||||
VideoEvent &weDisableChecker,
|
||||
M3ExtraCycles &m3ExtraCycles) :
|
||||
VideoEvent(7),
|
||||
m3EventQueue(m3EventQueue_in),
|
||||
weEnableChecker(weEnableChecker_in),
|
||||
weDisableChecker(weDisableChecker_in)
|
||||
m3EventQueue(m3EventQueue),
|
||||
weEnableChecker(weEnableChecker),
|
||||
weDisableChecker(weDisableChecker),
|
||||
m3ExtraCycles(m3ExtraCycles)
|
||||
{
|
||||
setDoubleSpeed(false);
|
||||
setSource(0);
|
||||
@ -47,6 +50,8 @@ void WxReader::doEvent() {
|
||||
rescheduleEvent(weEnableChecker, diff);
|
||||
rescheduleEvent(weDisableChecker, diff);
|
||||
|
||||
m3ExtraCycles.invalidateCache();
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define WX_READER_H
|
||||
|
||||
template<typename T, class Comparer> class event_queue;
|
||||
class M3ExtraCycles;
|
||||
|
||||
#include "video_event.h"
|
||||
#include "video_event_comparer.h"
|
||||
@ -29,6 +30,7 @@ class WxReader : public VideoEvent {
|
||||
event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue;
|
||||
VideoEvent &weEnableChecker;
|
||||
VideoEvent &weDisableChecker;
|
||||
M3ExtraCycles &m3ExtraCycles;
|
||||
|
||||
unsigned char wx_;
|
||||
unsigned char src_;
|
||||
@ -39,7 +41,8 @@ class WxReader : public VideoEvent {
|
||||
public:
|
||||
WxReader(event_queue<VideoEvent*,VideoEventComparer> &m3EventQueue_in,
|
||||
VideoEvent &weEnableChecker_in,
|
||||
VideoEvent &weDisableChecker_in);
|
||||
VideoEvent &weDisableChecker_in,
|
||||
M3ExtraCycles &m3ExtraCycles);
|
||||
|
||||
void doEvent();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007 by Sindre Aam<EFBFBD>s *
|
||||
* Copyright (C) 2007 by Sindre Aamås *
|
||||
* aamas@stud.ntnu.no *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -22,83 +22,77 @@
|
||||
#include "scx_reader.h"
|
||||
#include "../event_queue.h"
|
||||
|
||||
Wy::WyReader1::WyReader1(unsigned char &wy, const unsigned char &src, const LyCounter &lyCounter, const WeMasterChecker &weMasterChecker) :
|
||||
Wy::WyReader1::WyReader1(Wy &wy, const WeMasterChecker &weMasterChecker) :
|
||||
VideoEvent(3),
|
||||
lyCounter(lyCounter),
|
||||
weMasterChecker(weMasterChecker),
|
||||
wy(wy),
|
||||
src(src)
|
||||
weMasterChecker(weMasterChecker)
|
||||
{}
|
||||
|
||||
void Wy::WyReader1::doEvent() {
|
||||
if (src >= lyCounter.ly() && /*wy >= lyCounter.ly()*/ !weMasterChecker.weMaster()) {
|
||||
wy = src;
|
||||
}
|
||||
if (wy.src_ >= wy.lyCounter.ly() && /*wy >= lyCounter.ly()*/ !weMasterChecker.weMaster())
|
||||
wy.set(wy.src_);
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
Wy::WyReader2::WyReader2(unsigned char &wy_in, const unsigned char &src_in, const LyCounter &lyCounter_in) :
|
||||
Wy::WyReader2::WyReader2(Wy &wy) :
|
||||
VideoEvent(4),
|
||||
lyCounter(lyCounter_in),
|
||||
wy(wy_in),
|
||||
src(src_in)
|
||||
wy(wy)
|
||||
{}
|
||||
|
||||
void Wy::WyReader2::doEvent() {
|
||||
if (wy == lyCounter.ly() + 1 - lyCounter.isDoubleSpeed() && src > wy)
|
||||
wy = src;
|
||||
if (wy.wy_ == wy.lyCounter.ly() + 1 - wy.lyCounter.isDoubleSpeed() && wy.src_ > wy.wy_)
|
||||
wy.set(wy.src_);
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
Wy::WyReader3::WyReader3(unsigned char &wy_in, const unsigned char &src_in, const LyCounter &lyCounter_in) :
|
||||
Wy::WyReader3::WyReader3(Wy &wy) :
|
||||
VideoEvent(5),
|
||||
lyCounter(lyCounter_in),
|
||||
wy(wy_in),
|
||||
src(src_in)
|
||||
wy(wy)
|
||||
{}
|
||||
|
||||
void Wy::WyReader3::doEvent() {
|
||||
if (src == lyCounter.ly() && wy > lyCounter.ly())
|
||||
wy = src;
|
||||
if (wy.src_ == wy.lyCounter.ly() && wy.wy_ > wy.lyCounter.ly())
|
||||
wy.set(wy.src_);
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
void Wy::WyReader3::schedule(const unsigned wxSrc, const ScxReader &scxReader, const unsigned long cycleCounter) {
|
||||
const unsigned curLineCycle = 456 - (lyCounter.time() - cycleCounter >> lyCounter.isDoubleSpeed());
|
||||
const unsigned baseTime = 78 + lyCounter.isDoubleSpeed() * 6 + wxSrc;
|
||||
const unsigned curLineCycle = 456 - (wy.lyCounter.time() - cycleCounter >> wy.lyCounter.isDoubleSpeed());
|
||||
const unsigned baseTime = 78 + wy.lyCounter.isDoubleSpeed() * 6 + wxSrc;
|
||||
|
||||
if (curLineCycle >= 82U + lyCounter.isDoubleSpeed() * 3) {
|
||||
if (curLineCycle >= 82U + wy.lyCounter.isDoubleSpeed() * 3) {
|
||||
if (baseTime + scxReader.scxAnd7() > curLineCycle)
|
||||
setTime(lyCounter.time() + (baseTime + scxReader.scxAnd7() << lyCounter.isDoubleSpeed()) - lyCounter.lineTime());
|
||||
setTime(wy.lyCounter.time() + (baseTime + scxReader.scxAnd7() << wy.lyCounter.isDoubleSpeed()) - wy.lyCounter.lineTime());
|
||||
else
|
||||
setTime(lyCounter.time() + (baseTime + scxReader.getSource() << lyCounter.isDoubleSpeed()));
|
||||
setTime(wy.lyCounter.time() + (baseTime + scxReader.getSource() << wy.lyCounter.isDoubleSpeed()));
|
||||
} else
|
||||
setTime(lyCounter.nextLineCycle(baseTime + scxReader.getSource(), cycleCounter));
|
||||
setTime(wy.lyCounter.nextLineCycle(baseTime + scxReader.getSource(), cycleCounter));
|
||||
}
|
||||
|
||||
Wy::WyReader4::WyReader4(unsigned char &wy_in, const unsigned char &src_in) :
|
||||
Wy::WyReader4::WyReader4(Wy &wy) :
|
||||
VideoEvent(6),
|
||||
wy(wy_in),
|
||||
src(src_in)
|
||||
wy(wy)
|
||||
{}
|
||||
|
||||
void Wy::WyReader4::doEvent() {
|
||||
wy = src;
|
||||
wy.set(wy.src_);
|
||||
|
||||
setTime(DISABLED_TIME);
|
||||
}
|
||||
|
||||
Wy::Wy(const LyCounter &lyCounter, const WeMasterChecker &weMasterChecker) :
|
||||
reader1_(wy_, src_, lyCounter, weMasterChecker),
|
||||
reader2_(wy_, src_, lyCounter),
|
||||
reader3_(wy_, src_, lyCounter),
|
||||
reader4_(wy_, src_)
|
||||
Wy::Wy(const LyCounter &lyCounter, const WeMasterChecker &weMasterChecker, M3ExtraCycles &m3ExtraCycles) :
|
||||
lyCounter(lyCounter),
|
||||
m3ExtraCycles(m3ExtraCycles),
|
||||
reader1_(*this, weMasterChecker),
|
||||
reader2_(*this),
|
||||
reader3_(*this),
|
||||
reader4_(*this)
|
||||
{
|
||||
setSource(0);
|
||||
reset();
|
||||
wy_ = src_;
|
||||
}
|
||||
|
||||
void Wy::reset() {
|
||||
|
@ -26,16 +26,16 @@ template<typename T, class Comparer> class event_queue;
|
||||
#include "video_event.h"
|
||||
#include "video_event_comparer.h"
|
||||
#include "ly_counter.h"
|
||||
#include "m3_extra_cycles.h"
|
||||
|
||||
class Wy {
|
||||
public:
|
||||
class WyReader1 : public VideoEvent {
|
||||
const LyCounter &lyCounter;
|
||||
Wy &wy;
|
||||
const WeMasterChecker &weMasterChecker;
|
||||
unsigned char &wy;
|
||||
const unsigned char &src;
|
||||
|
||||
public:
|
||||
WyReader1(unsigned char &wy_in, const unsigned char &src_in, const LyCounter &lyCounter_in, const WeMasterChecker &weMasterChecker);
|
||||
WyReader1(Wy &wy, const WeMasterChecker &weMasterChecker);
|
||||
|
||||
void doEvent();
|
||||
|
||||
@ -45,12 +45,10 @@ class Wy {
|
||||
};
|
||||
|
||||
class WyReader2 : public VideoEvent {
|
||||
const LyCounter &lyCounter;
|
||||
unsigned char &wy;
|
||||
const unsigned char &src;
|
||||
Wy &wy;
|
||||
|
||||
public:
|
||||
WyReader2(unsigned char &wy_in, const unsigned char &src_in, const LyCounter &lyCounter_in);
|
||||
WyReader2(Wy &wy);
|
||||
|
||||
void doEvent();
|
||||
|
||||
@ -59,28 +57,11 @@ class Wy {
|
||||
}
|
||||
};
|
||||
|
||||
class WyReader4 : public VideoEvent {
|
||||
unsigned char &wy;
|
||||
const unsigned char &src;
|
||||
|
||||
public:
|
||||
WyReader4(unsigned char &wy_in, const unsigned char &src_in);
|
||||
|
||||
void doEvent();
|
||||
|
||||
void schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) {
|
||||
setTime(lyCounter.nextFrameCycle(lyCounter.isDoubleSpeed() * 4, cycleCounter));
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
class WyReader3 : public VideoEvent {
|
||||
const LyCounter &lyCounter;
|
||||
unsigned char &wy;
|
||||
const unsigned char &src;
|
||||
Wy &wy;
|
||||
|
||||
public:
|
||||
WyReader3(unsigned char &wy_in, const unsigned char &src_in, const LyCounter &lyCounter_in);
|
||||
WyReader3(Wy &wy);
|
||||
|
||||
void doEvent();
|
||||
void schedule(unsigned wxSrc, const ScxReader &scxReader, unsigned long cycleCounter);
|
||||
@ -90,7 +71,27 @@ public:
|
||||
//}
|
||||
};
|
||||
|
||||
class WyReader4 : public VideoEvent {
|
||||
Wy &wy;
|
||||
|
||||
public:
|
||||
WyReader4(Wy &wy);
|
||||
|
||||
void doEvent();
|
||||
|
||||
void schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) {
|
||||
setTime(lyCounter.nextFrameCycle(lyCounter.isDoubleSpeed() * 4, cycleCounter));
|
||||
}
|
||||
};
|
||||
|
||||
friend class WyReader1;
|
||||
friend class WyReader2;
|
||||
friend class WyReader3;
|
||||
friend class WyReader4;
|
||||
|
||||
private:
|
||||
const LyCounter &lyCounter;
|
||||
M3ExtraCycles &m3ExtraCycles;
|
||||
WyReader1 reader1_;
|
||||
WyReader2 reader2_;
|
||||
WyReader3 reader3_;
|
||||
@ -99,8 +100,15 @@ private:
|
||||
unsigned char wy_;
|
||||
unsigned char src_;
|
||||
|
||||
void set(const unsigned char value) {
|
||||
if (wy_ != value)
|
||||
m3ExtraCycles.invalidateCache();
|
||||
|
||||
wy_ = value;
|
||||
}
|
||||
|
||||
public:
|
||||
Wy(const LyCounter &lyCounter, const WeMasterChecker &weMasterChecker);
|
||||
Wy(const LyCounter &lyCounter, const WeMasterChecker &weMasterChecker, M3ExtraCycles &m3ExtraCycles);
|
||||
|
||||
WyReader1& reader1() {
|
||||
return reader1_;
|
||||
@ -128,16 +136,16 @@ public:
|
||||
src_ = src;
|
||||
}
|
||||
|
||||
void setValue(const unsigned val) {
|
||||
wy_ = val;
|
||||
}
|
||||
//void setValue(const unsigned val) {
|
||||
// wy_ = val;
|
||||
//}
|
||||
|
||||
unsigned value() const {
|
||||
return wy_;
|
||||
}
|
||||
|
||||
void weirdAssWeMasterEnableOnWyLineCase() {
|
||||
++wy_;
|
||||
set(wy_ + 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user