~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/VideoBackends/Software/Src/BPMemLoader.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Dolphin Emulator Project
 
2
// Licensed under GPLv2
 
3
// Refer to the license.txt file included.
 
4
 
 
5
#include "VideoCommon.h"
 
6
#include "TextureDecoder.h"
 
7
 
 
8
#include "BPMemLoader.h"
 
9
#include "EfbCopy.h"
 
10
#include "Rasterizer.h"
 
11
#include "SWPixelEngine.h"
 
12
#include "Tev.h"
 
13
#include "HW/Memmap.h"
 
14
#include "Core.h"
 
15
 
 
16
 
 
17
void InitBPMemory()
 
18
{
 
19
        memset(&bpmem, 0, sizeof(bpmem));
 
20
        bpmem.bpMask = 0xFFFFFF;
 
21
}
 
22
 
 
23
void SWLoadBPReg(u32 value)
 
24
{
 
25
        //handle the mask register
 
26
        int address = value >> 24;
 
27
        int oldval = ((u32*)&bpmem)[address];
 
28
        int newval = (oldval & ~bpmem.bpMask) | (value & bpmem.bpMask);
 
29
 
 
30
        ((u32*)&bpmem)[address] = newval;
 
31
 
 
32
        //reset the mask register
 
33
        if (address != 0xFE)
 
34
                bpmem.bpMask = 0xFFFFFF;
 
35
 
 
36
        SWBPWritten(address, newval);
 
37
}
 
38
 
 
39
void SWBPWritten(int address, int newvalue)
 
40
{
 
41
        switch (address)
 
42
        {
 
43
        case BPMEM_SCISSORTL:
 
44
        case BPMEM_SCISSORBR:
 
45
        case BPMEM_SCISSOROFFSET:
 
46
                Rasterizer::SetScissor();
 
47
                break;
 
48
        case BPMEM_SETDRAWDONE: // This is called when the game is done drawing (eg: like in DX: Begin(); Draw(); End();)
 
49
                switch (bpmem.drawdone & 0xFF)
 
50
                {
 
51
                case 0x02:
 
52
                        SWPixelEngine::SetFinish(); // may generate interrupt
 
53
                        DEBUG_LOG(VIDEO, "GXSetDrawDone SetPEFinish (value: 0x%02X)", (bpmem.drawdone & 0xFFFF));
 
54
                        break;
 
55
 
 
56
                default:
 
57
                        WARN_LOG(VIDEO, "GXSetDrawDone ??? (value 0x%02X)", (bpmem.drawdone & 0xFFFF));
 
58
                        break;
 
59
                }
 
60
                break;
 
61
        case BPMEM_PE_TOKEN_ID: // Pixel Engine Token ID
 
62
                DEBUG_LOG(VIDEO, "SetPEToken 0x%04x", (bpmem.petoken & 0xFFFF));
 
63
                SWPixelEngine::SetToken(static_cast<u16>(bpmem.petokenint & 0xFFFF), false);
 
64
                break;
 
65
        case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID
 
66
                DEBUG_LOG(VIDEO, "SetPEToken + INT 0x%04x", (bpmem.petokenint & 0xFFFF));
 
67
                SWPixelEngine::SetToken(static_cast<u16>(bpmem.petokenint & 0xFFFF), true);
 
68
                break;
 
69
        case BPMEM_TRIGGER_EFB_COPY:
 
70
                EfbCopy::CopyEfb();
 
71
                break;
 
72
        case BPMEM_CLEARBBOX1:
 
73
                SWPixelEngine::pereg.boxRight = newvalue >> 10;
 
74
                SWPixelEngine::pereg.boxLeft = newvalue & 0x3ff;
 
75
                break;
 
76
        case BPMEM_CLEARBBOX2:
 
77
                SWPixelEngine::pereg.boxBottom = newvalue >> 10;
 
78
                SWPixelEngine::pereg.boxTop = newvalue & 0x3ff;
 
79
                break;
 
80
        case BPMEM_CLEAR_PIXEL_PERF:
 
81
                // TODO: I didn't test if the value written to this register affects the amount of cleared registers
 
82
                SWPixelEngine::pereg.perfZcompInputZcomplocLo = 0;
 
83
                SWPixelEngine::pereg.perfZcompInputZcomplocHi = 0;
 
84
                SWPixelEngine::pereg.perfZcompOutputZcomplocLo = 0;
 
85
                SWPixelEngine::pereg.perfZcompOutputZcomplocHi = 0;
 
86
                SWPixelEngine::pereg.perfZcompInputLo = 0;
 
87
                SWPixelEngine::pereg.perfZcompInputHi = 0;
 
88
                SWPixelEngine::pereg.perfZcompOutputLo = 0;
 
89
                SWPixelEngine::pereg.perfZcompOutputHi = 0;
 
90
                SWPixelEngine::pereg.perfBlendInputLo = 0;
 
91
                SWPixelEngine::pereg.perfBlendInputHi = 0;
 
92
                SWPixelEngine::pereg.perfEfbCopyClocksLo = 0;
 
93
                SWPixelEngine::pereg.perfEfbCopyClocksHi = 0;
 
94
                break;
 
95
        case BPMEM_LOADTLUT0: // This one updates bpmem.tlutXferSrc, no need to do anything here.
 
96
                break;
 
97
        case BPMEM_LOADTLUT1: // Load a Texture Look Up Table
 
98
                {
 
99
                        u32 tlutTMemAddr = (newvalue & 0x3FF) << 9;
 
100
                        u32 tlutXferCount = (newvalue & 0x1FFC00) >> 5; 
 
101
 
 
102
                        u8 *ptr = 0;
 
103
 
 
104
                        // TODO - figure out a cleaner way.
 
105
                        if (Core::g_CoreStartupParameter.bWii)
 
106
                                ptr = Memory::GetPointer(bpmem.tmem_config.tlut_src << 5);
 
107
                        else
 
108
                                ptr = Memory::GetPointer((bpmem.tmem_config.tlut_src & 0xFFFFF) << 5);
 
109
 
 
110
                        if (ptr)
 
111
                                memcpy_gc(texMem + tlutTMemAddr, ptr, tlutXferCount);
 
112
                        else
 
113
                                PanicAlert("Invalid palette pointer %08x %08x %08x", bpmem.tmem_config.tlut_src, bpmem.tmem_config.tlut_src << 5, (bpmem.tmem_config.tlut_src & 0xFFFFF)<< 5);
 
114
                        break;
 
115
                }
 
116
 
 
117
        case BPMEM_PRELOAD_MODE:
 
118
                if (newvalue != 0)
 
119
                {
 
120
                        // TODO: Not quite sure if this is completely correct (likely not)
 
121
                        // NOTE: libogc's implementation of GX_PreloadEntireTexture seems flawed, so it's not necessarily a good reference for RE'ing this feature.
 
122
 
 
123
                        BPS_TmemConfig& tmem_cfg = bpmem.tmem_config;
 
124
                        u8* src_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); // TODO: Should we add mask here on GC?
 
125
                        u32 size = tmem_cfg.preload_tile_info.count * TMEM_LINE_SIZE;
 
126
                        u32 tmem_addr_even = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE;
 
127
 
 
128
                        if (tmem_cfg.preload_tile_info.type != 3)
 
129
                        {
 
130
                                if (tmem_addr_even + size > TMEM_SIZE)
 
131
                                        size = TMEM_SIZE - tmem_addr_even;
 
132
 
 
133
                                memcpy(texMem + tmem_addr_even, src_ptr, size);
 
134
                        }
 
135
                        else // RGBA8 tiles (and CI14, but that might just be stupid libogc!)
 
136
                        {
 
137
                                // AR and GB tiles are stored in separate TMEM banks => can't use a single memcpy for everything
 
138
                                u32 tmem_addr_odd = tmem_cfg.preload_tmem_odd * TMEM_LINE_SIZE;
 
139
 
 
140
                                for (unsigned int i = 0; i < tmem_cfg.preload_tile_info.count; ++i)
 
141
                                {
 
142
                                        if (tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE ||
 
143
                                                tmem_addr_odd  + TMEM_LINE_SIZE > TMEM_SIZE)
 
144
                                                break;
 
145
 
 
146
                                        memcpy(texMem + tmem_addr_even, src_ptr, TMEM_LINE_SIZE);
 
147
                                        memcpy(texMem + tmem_addr_odd, src_ptr + TMEM_LINE_SIZE, TMEM_LINE_SIZE);
 
148
                                        tmem_addr_even += TMEM_LINE_SIZE;
 
149
                                        tmem_addr_odd += TMEM_LINE_SIZE;
 
150
                                        src_ptr += TMEM_LINE_SIZE * 2;
 
151
                                }
 
152
                        }
 
153
                }
 
154
                break;
 
155
 
 
156
        case BPMEM_TEV_REGISTER_L:   // Reg 1
 
157
        case BPMEM_TEV_REGISTER_L+2: // Reg 2
 
158
        case BPMEM_TEV_REGISTER_L+4: // Reg 3
 
159
        case BPMEM_TEV_REGISTER_L+6: // Reg 4
 
160
                {
 
161
                        int regNum = (address >> 1 ) & 0x3;
 
162
                        ColReg& reg = bpmem.tevregs[regNum].low;
 
163
                        bool konst = reg.type;
 
164
 
 
165
                        Rasterizer::SetTevReg(regNum, Tev::ALP_C, konst, reg.b); // A
 
166
                        Rasterizer::SetTevReg(regNum, Tev::RED_C, konst, reg.a); // R
 
167
 
 
168
                        break;
 
169
                }
 
170
 
 
171
        case BPMEM_TEV_REGISTER_H:   // Reg 1
 
172
        case BPMEM_TEV_REGISTER_H+2: // Reg 2
 
173
        case BPMEM_TEV_REGISTER_H+4: // Reg 3
 
174
        case BPMEM_TEV_REGISTER_H+6: // Reg 4
 
175
                {
 
176
                        int regNum = (address >> 1 ) & 0x3;
 
177
                        ColReg& reg = bpmem.tevregs[regNum].high;
 
178
                        bool konst = reg.type;
 
179
 
 
180
                        Rasterizer::SetTevReg(regNum, Tev::GRN_C, konst, reg.b); // G
 
181
                        Rasterizer::SetTevReg(regNum, Tev::BLU_C, konst, reg.a); // B
 
182
 
 
183
                        break;
 
184
                }
 
185
 
 
186
        }
 
187
}
 
188