Dungeon object updates

This commit is contained in:
scawful
2023-11-22 12:23:02 -05:00
parent e93ff212af
commit 041e365416
25 changed files with 311 additions and 150 deletions

View File

@@ -8,6 +8,7 @@
#include <vector>
#include "app/emu/cpu.h"
#include "app/emu/memory/memory.h"
#include "app/emu/video/ppu.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
@@ -31,8 +32,9 @@ class DungeonObjectRenderer : public SharedROM {
}
void LoadObject(uint16_t objectId) {
rom_data_ = rom()->vector();
// Prepare the CPU and memory environment
memory_.Initialize(rom()->vector());
memory_.Initialize(rom_data_);
// Fetch the subtype pointers for the given object ID
auto subtypeInfo = FetchSubtypeInfo(objectId);
@@ -44,11 +46,12 @@ class DungeonObjectRenderer : public SharedROM {
RenderObject(subtypeInfo);
}
gfx::Bitmap* bitmap() { return &bitmap_; }
private:
struct SubtypeInfo {
uint16_t subtypePtr;
uint16_t routinePtr;
// Additional fields as needed
uint32_t subtypePtr;
uint32_t routinePtr;
};
SubtypeInfo FetchSubtypeInfo(uint16_t objectId) {
@@ -56,13 +59,19 @@ class DungeonObjectRenderer : public SharedROM {
// Determine the subtype based on objectId
// Assuming subtype is determined by some bits in objectId; modify as needed
uint8_t subtype = (objectId >> 8) & 0xFF; // Example: top 8 bits
uint8_t subtype = 1; // Example: top 8 bits
// Based on the subtype, fetch the correct pointers
switch (subtype) {
case 1: // Subtype 1
info.subtypePtr = core::subtype1_tiles + (objectId & 0xFF) * 2;
info.routinePtr = core::subtype1_tiles + 0x200 + (objectId & 0xFF) * 2;
std::cout << "Subtype 1 " << std::hex << info.subtypePtr << std::endl;
info.routinePtr =
memory_.ReadWord(core::MapBankToWordAddress(0x01, info.routinePtr));
std::cout << "Subtype 1 " << std::hex << info.routinePtr << std::endl;
std::cout << "Subtype 1 " << std::hex << core::SnesToPc(info.routinePtr)
<< std::endl;
break;
case 2: // Subtype 2
info.subtypePtr = core::subtype2_tiles + (objectId & 0x7F) * 2;
@@ -86,13 +95,57 @@ class DungeonObjectRenderer : public SharedROM {
}
void ConfigureObject(const SubtypeInfo& info) {
// TODO: Use the information in info to set up the object's initial state
cpu.A = 0x00;
cpu.X = 0x00;
// Might need to set the height and width manually?
}
/**
* Example:
* the STA $BF, $CD, $C2, $CE are the location of the object in the room
* $B2 is used for size loop
* so if object size is setted on 07 that draw code will be repeated 7 times
* and since Y is increasing by 4 it makes the object draw from left to right
RoomDraw_Rightwards2x2_1to15or32:
#_018B89: JSR RoomDraw_GetSize_1to15or32
.next
#_018B8C: JSR RoomDraw_Rightwards2x2
#_018B8F: DEC.b $B2
#_018B91: BNE .next
#_018B93: RTS
RoomDraw_Rightwards2x2:
#_019895: LDA.w RoomDrawObjectData+0,X
#_019898: STA.b [$BF],Y
#_01989A: LDA.w RoomDrawObjectData+2,X
#_01989D: STA.b [$CB],Y
#_01989F: LDA.w RoomDrawObjectData+4,X
#_0198A2: STA.b [$C2],Y
#_0198A4: LDA.w RoomDrawObjectData+6,X
#_0198A7: STA.b [$CE],Y
#_0198A9: INY
#_0198AA: INY
#_0198AB: INY
#_0198AC: INY
#_0198AD: RTS
*
*/
void RenderObject(const SubtypeInfo& info) {
cpu.PC = info.routinePtr;
cpu.PB = 0x01;
int i = 0;
while (true) {
uint8_t opcode = cpu.FetchByte();
cpu.ExecuteInstruction(opcode);
@@ -103,12 +156,32 @@ class DungeonObjectRenderer : public SharedROM {
break;
}
if (i > 50) {
break;
}
i++;
UpdateObjectBitmap();
}
}
void UpdateObjectBitmap() {
// TODO: Implement logic to transfer object draw data to the Bitmap
// Object draw data
uint8_t room_object_draw_data0 = memory_.ReadByte(0x7E00BF);
uint8_t room_object_draw_data1 = memory_.ReadByte(0x7E00CB);
uint8_t room_object_draw_data2 = memory_.ReadByte(0x7E00C2);
uint8_t room_object_draw_data3 = memory_.ReadByte(0x7E00CE);
// Used with Y to index the room object draw data
uint8_t size_loop = memory_.ReadByte(0x7E00B2);
// Update the bitmap with this data by copying the tiles from vram.
std::cout << "Object draw data: " << std::hex << (int)room_object_draw_data0
<< " " << (int)room_object_draw_data1 << " "
<< (int)room_object_draw_data2 << " "
<< (int)room_object_draw_data3 << std::endl;
std::cout << "Size loop: " << std::hex << (int)size_loop << std::endl;
}
std::vector<uint8_t> rom_data_;
@@ -116,7 +189,7 @@ class DungeonObjectRenderer : public SharedROM {
emu::ClockImpl clock_;
emu::CPU cpu{memory_, clock_};
emu::PPU ppu{memory_, clock_};
gfx::Bitmap bitmap;
gfx::Bitmap bitmap_;
PseudoVram vram_;
};