From: Shamus Hammons Date: Thu, 6 Nov 2003 16:40:59 +0000 (+0000) Subject: 1.0.7 update X-Git-Tag: 1.0.7~91 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=59ca39a29be645918de45bd144865ba6487f4009;p=virtualjaguar 1.0.7 update --- diff --git a/src/blitter.cpp b/src/blitter.cpp index 888abea..9ecba6f 100644 --- a/src/blitter.cpp +++ b/src/blitter.cpp @@ -859,6 +859,20 @@ void blitter_blit(uint32 cmd) a1_yadd = (REG(A1_INC) & 0xFFFF0000) | (REG(A1_FINC) >> 16); break; } + + +//Blit! (0011D000 -> 000B9600) count: 228 x 1, A1/2_FLAGS: 00073820/00064220 [cmd: 41802801] +// A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 128 (1C), addctl: XADDINC YADD1 XSIGNADD YSIGNADD +// A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADD0 YADD1 XSIGNADD YSIGNADD +//if (YADD1_A1 && YADD1_A2 && xadd_a2_control == XADD0 && xadd_a1_control == XADDINC)// && +// UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS); +//Ok, so this ISN'T it... Prolly the XADDPHR code above that's doing it... +//if (REG(A1_FLAGS) == 0x00073820 && REG(A2_FLAGS) == 0x00064220 && cmd == 0x41802801) +// A1 x/y: 14368/7, A2 x/y: 150/36 +//This is it... The problem... +//if ((a1_x >> 16) == 14368) // 14368 = $3820 +// return; //Lesse what we got... + if (XSIGNSUB_A1) a1_xadd = -a1_xadd; @@ -892,6 +906,7 @@ WriteLog("BLIT: Asked to use invalid bit combo (XADDINC) for A2...\n"); // a2_xadd = 1 << 16; break; } + if (XSIGNSUB_A2) a2_xadd = -a2_xadd; @@ -1284,14 +1299,21 @@ uint8 BlitterReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) if (offset == (0x38 + 3)) return 0x01; // always idle +//Attempted fix for AvP: + if (offset >= 0x04 && offset <= 0x07) + return (offset > 0x05 ? blitter_ram[PIXLINECOUNTER + offset - 0x04] : 0x00); +// return 0x00; // WO register! What does it expect to see here??? + return blitter_ram[offset]; } +//Crappy! uint16 BlitterReadWord(uint32 offset, uint32 who/*=UNKNOWN*/) { return ((uint16)BlitterReadByte(offset, who) << 8) | (uint16)BlitterReadByte(offset+1, who); } +//Crappy! uint32 BlitterReadLong(uint32 offset, uint32 who/*=UNKNOWN*/) { return (BlitterReadWord(offset, who) << 16) | BlitterReadWord(offset+2, who); @@ -1338,6 +1360,21 @@ void BlitterWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) void BlitterWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/) { +//#if 1 +/* if (offset & 0xFF == A1_PIXEL && data == 14368) + { + WriteLog("\n1\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data); +extern bool doGPUDis; +doGPUDis = true; + } + if ((offset & 0xFF) == (A1_PIXEL + 2) && data == 14368) + { + WriteLog("\n2\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data); +extern bool doGPUDis; +doGPUDis = true; + }//*/ +//#endif + BlitterWriteByte(offset+0, (data>>8) & 0xFF, who); BlitterWriteByte(offset+1, data & 0xFF, who); @@ -1345,14 +1382,20 @@ void BlitterWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/) // I.e., the second write of 32-bit value--not convinced this is the best way to do this! // But then again, according to the Jaguar docs, this is correct...! blitter_blit(GET32(blitter_ram, 0x38)); -// Testing purposes only! -//This does the clipping correctly, but not the Gouraud shading... -// blitter2_exec(GET32(blitter_ram, 0x38)); } //F02278,9,A,B void BlitterWriteLong(uint32 offset, uint32 data, uint32 who/*=UNKNOWN*/) { +//#if 1 +/* if ((offset & 0xFF) == A1_PIXEL && (data & 0xFFFF) == 14368) + { + WriteLog("\n3\nA1_PIXEL written by %s (%u)...\n\n\n", whoName[who], data); +extern bool doGPUDis; +doGPUDis = true; + }//*/ +//#endif + BlitterWriteWord(offset, data >> 16, who); BlitterWriteWord(offset+2, data & 0xFFFF, who); } diff --git a/src/gpu.cpp b/src/gpu.cpp index f1d9c72..b7e0ae6 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -1,7 +1,7 @@ // // GPU Core // -// by Cal2 +// Originally by David Raingeard (Cal2) // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) // Cleanups, endian wrongness, and bad ASM amelioration by James L. Hammons // Note: Endian wrongness probably stems from the MAME origins of this emu and @@ -1593,7 +1593,7 @@ static void gpu_opcode_move_pc(void) { #ifdef GPU_DIS_MOVEPC if (doGPUDis) - WriteLog("%06X: MOVE PC, R%02u [NCZ:%u%u%u, PC=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_pc-2, IMM_2, RN); + WriteLog("%06X: MOVE PC, R%02u [NCZ:%u%u%u, PC=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_pc-2, IMM_2, RN); #endif // Should be previous PC--this might not always be previous instruction! // Then again, this will point right at the *current* instruction, i.e., MOVE PC,R! diff --git a/src/gui.cpp b/src/gui.cpp index 4797e60..730ae71 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -34,6 +34,7 @@ Window * ResetJaguar(void); Window * RunEmu(void); Window * Quit(void); Window * About(void); +Window * MiscOptions(void); int gzfilelength(gzFile gd); @@ -113,6 +114,87 @@ uint16 downArrowBox[] = { 0x0217,0x0217,0x0217,0x0217,0x0217,0x0217,0x0217,0x0217 // ........ }; +uint16 pushButtonUp[] = { + 8, 8, + + 0x0000,0x0000,0x0000,0x000A,0x000A,0x0000,0x0000,0x0000, // ...##... + 0x0000,0x000A,0x000A,0x000A,0x000A,0x000A,0x000A,0x0000, // .######. + 0x0000,0x000A,0x000A,0x000A,0x000A,0x000A,0x000A,0x0000, // .######. + 0x000A,0x000A,0x000A,0x000A,0x000A,0x000A,0x000A,0x000A, // ######## + 0x000A,0x000A,0x000A,0x000A,0x000A,0x000A,0x000A,0x000A, // ######## + 0x0000,0x000A,0x000A,0x000A,0x000A,0x000A,0x000A,0x0000, // .######. + 0x0000,0x000A,0x000A,0x000A,0x000A,0x000A,0x000A,0x0000, // .######. + 0x0000,0x0000,0x0000,0x000A,0x000A,0x0000,0x0000,0x0000 // ...##... +}; + +uint16 pushButtonDown[] = { + 8, 8, + + 0x0000,0x0000,0x0000,0x000A,0x000A,0x0000,0x0000,0x0000, // ...@@... + 0x0000,0x000A,0x000A,0x0C7F,0x0C7F,0x000A,0x000A,0x0000, // .@@##@@. + 0x0000,0x000A,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x000A,0x0000, // .@####@. + 0x000A,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x000A, // @######@ + 0x000A,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x000A, // @######@ + 0x0000,0x000A,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x000A,0x0000, // .@####@. + 0x0000,0x000A,0x000A,0x0C7F,0x0C7F,0x000A,0x000A,0x0000, // .@@##@@. + 0x0000,0x0000,0x0000,0x000A,0x000A,0x0000,0x0000,0x0000 // ...@@... +}; + +uint16 slideSwitchUp[] = { + 8, 16, + + 0x4B5E,0x4B5E,0x4B5E,0x4B5E,0x4B5E,0x4B5E,0x4B5E,0x4B5E, // ++++++++ + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x0217,0x0217,0x0217,0x0217,0x0217,0x0217,0x0217,0x0217 // ........ +}; + +uint16 slideSwitchDown[] = { + 8, 16, + + 0x4B5E,0x4B5E,0x4B5E,0x4B5E,0x4B5E,0x4B5E,0x4B5E,0x4B5E, // ++++++++ + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0217, // +....... + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x4B5E,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0C7F,0x0217, // + . + 0x0217,0x0217,0x0217,0x0217,0x0217,0x0217,0x0217,0x0217 // ........ +}; + +/*uint16 [] = { + 8, 8, + + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // ........ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // ........ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // ........ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // ........ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // ........ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // ........ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // ........ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 // ........ +};*/ + char separator[] = "--------------------------------------------------------"; uint16 background[1280 * 240]; @@ -156,6 +238,7 @@ bool Element::Inside(uint32 x, uint32 y) && y >= (uint32)extents.y && y < (uint32)(extents.y + extents.h) ? true : false); } + class Button: public Element { public: @@ -239,6 +322,160 @@ void Button::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) DrawString(screenBuffer, extents.x + offsetX, extents.y + offsetY, false, "%s", text.c_str()); } + +class PushButton: public Element +{ +// How to handle? +// Save state externally? + + public: +// PushButton(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0): Element(x, y, w, h), +// activated(false), clicked(false), inside(false), fgColor(0xFFFF), +// bgColor(0x03E0), pic(NULL), elementToTell(NULL) {} + PushButton(uint32 x, uint32 y, bool * st, string s): Element(x, y, 8, 8), state(st), + inside(false), text(s) { if (st == NULL) state = &internalState; } +/* Button(uint32 x, uint32 y, uint32 w, uint32 h, uint16 * p): Element(x, y, w, h), + activated(false), clicked(false), inside(false), fgColor(0xFFFF), + bgColor(0x03E0), pic(p), elementToTell(NULL) {} + Button(uint32 x, uint32 y, uint16 * p): Element(x, y, 0, 0), + activated(false), clicked(false), inside(false), fgColor(0xFFFF), + bgColor(0x03E0), pic(p), elementToTell(NULL) + { if (pic) extents.w = pic[0], extents.h = pic[1]; } + Button(uint32 x, uint32 y, uint32 w, uint32 h, string s): Element(x, y, w, h), + activated(false), clicked(false), inside(false), fgColor(0xFFFF), + bgColor(0x03E0), pic(NULL), text(s), elementToTell(NULL) {} + PushButton(uint32 x, uint32 y, string s): Element(x, y, 0, 8), + activated(false), clicked(false), inside(false), fgColor(0xFFFF), + bgColor(0x03E0), pic(NULL), text(s), elementToTell(NULL) + { extents.w = s.length() * 8; }*/ + virtual void HandleKey(SDLKey key) {} + virtual void HandleMouseMove(uint32 x, uint32 y); + virtual void HandleMouseButton(uint32 x, uint32 y, bool mouseDown); + virtual void Draw(uint32 offsetX = 0, uint32 offsetY = 0); + virtual void Notify(Element *) {} +// bool ButtonClicked(void) { return activated; } +// void SetNotificationElement(Element * e) { elementToTell = e; } + + protected: + bool * state; + bool inside; +// bool activated, clicked, inside; +// uint16 fgColor, bgColor; +// uint16 * pic; + string text; +// Element * elementToTell; + bool internalState; +}; + +void PushButton::HandleMouseMove(uint32 x, uint32 y) +{ + inside = Inside(x, y); +} + +void PushButton::HandleMouseButton(uint32 x, uint32 y, bool mouseDown) +{ + if (inside && mouseDown) + { +/* if (mouseDown) + clicked = true; + + if (clicked && !mouseDown) + { + clicked = false, activated = true; + + // Send a message that we're activated (if there's someone to tell, that is) + if (elementToTell) + elementToTell->Notify(this); + }*/ + *state = !(*state); + } +// else +// clicked = activated = false; +} + +void PushButton::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) +{ +/* uint32 addr = (extents.x + offsetX) + ((extents.y + offsetY) * pitch); + + for(uint32 y=0; y 0) + DrawString(screenBuffer, extents.x + offsetX + 12, extents.y + offsetY, false, "%s", text.c_str()); +} + + +class SlideSwitch: public Element +{ +// How to handle? +// Save state externally? + + public: + SlideSwitch(uint32 x, uint32 y, bool * st, string s1, string s2): Element(x, y, 8, 16), state(st), + inside(false), text1(s1), text2(s2) {} + virtual void HandleKey(SDLKey key) {} + virtual void HandleMouseMove(uint32 x, uint32 y); + virtual void HandleMouseButton(uint32 x, uint32 y, bool mouseDown); + virtual void Draw(uint32 offsetX = 0, uint32 offsetY = 0); + virtual void Notify(Element *) {} +// bool ButtonClicked(void) { return activated; } +// void SetNotificationElement(Element * e) { elementToTell = e; } + + protected: + bool * state; + bool inside; +// bool activated, clicked, inside; +// uint16 fgColor, bgColor; +// uint16 * pic; + string text1, text2; +// Element * elementToTell; +}; + +void SlideSwitch::HandleMouseMove(uint32 x, uint32 y) +{ + inside = Inside(x, y); +} + +void SlideSwitch::HandleMouseButton(uint32 x, uint32 y, bool mouseDown) +{ + if (inside && mouseDown) + { +/* if (mouseDown) + clicked = true; + + if (clicked && !mouseDown) + { + clicked = false, activated = true; + + // Send a message that we're activated (if there's someone to tell, that is) + if (elementToTell) + elementToTell->Notify(this); + }*/ + *state = !(*state); + } +// else +// clicked = activated = false; +} + +void SlideSwitch::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) +{ + DrawTransparentBitmap(screenBuffer, extents.x + offsetX, extents.y + offsetY, (*state ? slideSwitchDown : slideSwitchUp)); + if (text1.length() > 0) + DrawString(screenBuffer, extents.x + offsetX + 12, extents.y + offsetY, false, "%s", text1.c_str()); + if (text2.length() > 0) + DrawString(screenBuffer, extents.x + offsetX + 12, extents.y + offsetY + 8, false, "%s", text2.c_str()); +} + + class Window: public Element { public: @@ -342,6 +579,7 @@ void Window::Notify(Element * e) } } + class Text: public Element { public: @@ -366,6 +604,7 @@ void Text::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) DrawString(screenBuffer, extents.x + offsetX, extents.y + offsetY, false, "%s", text.c_str()); } + class ListBox: public Element //class ListBox: public Window { @@ -491,8 +730,8 @@ void ListBox::HandleMouseMove(uint32 x, uint32 y) if (thumbClicked) { uint32 sbHeight = extents.h - 24, - thumb = (uint32)(((float)limit / (float)item.size()) * (float)sbHeight), - thumbStart = (uint32)(((float)windowPtr / (float)item.size()) * (float)sbHeight); + thumb = (uint32)(((float)limit / (float)item.size()) * (float)sbHeight);//, +// thumbStart = (uint32)(((float)windowPtr / (float)item.size()) * (float)sbHeight); //yRelativePoint is the spot on the thumb where we clicked... // int32 thumbDelta = y - yRelativePoint; @@ -614,6 +853,7 @@ string ListBox::GetSelectedItem(void) return item[windowPtr + cursor]; } + class FileList: public Window { public: @@ -676,16 +916,17 @@ void FileList::Notify(Element * e) strcat(filename, files->GetSelectedItem().c_str()); - uint32 romSize = JaguarLoadROM(jaguar_mainRom, filename); +// uint32 romSize = JaguarLoadROM(jaguar_mainRom, filename); + JaguarLoadCart(jaguar_mainRom, filename); - if (romSize == 0) +// if (romSize == 0) //We need better error checking here... !!! FIX !!! - WriteLog("VJ: Could not load ROM from file \"%s\"...", files->GetSelectedItem().c_str()); - else - { - jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romSize); - WriteLog("CRC: %08X\n", (unsigned int)jaguar_mainRom_crc32); - eeprom_init(); +// WriteLog("VJ: Could not load ROM from file \"%s\"...", files->GetSelectedItem().c_str()); +// else +// { +// jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romSize); +// WriteLog("CRC: %08X\n", (unsigned int)jaguar_mainRom_crc32); +// eeprom_init(); SDL_Event event; event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE; @@ -694,7 +935,7 @@ void FileList::Notify(Element * e) event.type = SDL_USEREVENT, event.user.code = MENU_ITEM_CHOSEN; event.user.data1 = (void *)ResetJaguar; SDL_PushEvent(&event); - } +// } } else Window::Notify(e); @@ -711,6 +952,7 @@ struct NameAction action(a), hotKey(k) {} }; + class MenuItems { public: @@ -904,6 +1146,7 @@ void Menu::Add(MenuItems mi) extents.w += (mi.title.length() + 2) * 8; } + //Do we even *need* this? class RootWindow: public Window { @@ -1086,7 +1329,7 @@ bool GUIMain(void) mi.item.clear(); mi.item.push_back(NameAction("Video...")); mi.item.push_back(NameAction("Audio...")); - mi.item.push_back(NameAction("Misc...")); + mi.item.push_back(NameAction("Misc...", MiscOptions, SDLK_m)); mainMenu.Add(mi); mi.title = "Info"; mi.item.clear(); @@ -1225,17 +1468,25 @@ Window * RunEmu(void) { //This is crappy... !!! FIX !!! extern int16 * backbuffer; - extern bool finished; - extern bool showGUI; + extern bool finished, showGUI; + uint32 nFrame = 0, nFrameskip = 0; uint32 totalFrames = 0; finished = false; bool showMessage = true; - uint32 showMsgFrames = 60; + uint32 showMsgFrames = 120; uint8 transparency = 0; // Pass a message to the "joystick" code to debounce the ESC key... debounceRunKey = true; + uint32 cartType = 2; + if (jaguarRomSize == 0x200000) + cartType = 0; + else if (jaguarRomSize == 0x400000) + cartType = 1; + + char * cartTypeName[3] = { "2M Cartridge", "4M Cartridge", "Homebrew" }; + while (!finished) { // Set up new backbuffer with new pixels and data @@ -1262,13 +1513,20 @@ Window * RunEmu(void) if (showMessage) { DrawStringTrans(backbuffer, 8, 24*8, 0xFF0F, transparency, "Running..."); + DrawStringTrans(backbuffer, 8, 26*8, 0x3FE3, transparency, "%s, run address: %06X", cartTypeName[cartType], jaguarRunAddress); + DrawStringTrans(backbuffer, 8, 27*8, 0x3FE3, transparency, "CRC: %08X", jaguar_mainRom_crc32); if (showMsgFrames == 0) { transparency++; if (transparency == 33) +{ showMessage = false; +/*extern bool doGPUDis; +doGPUDis = true;//*/ +} + } else showMsgFrames--; @@ -1304,8 +1562,16 @@ Window * RunEmu(void) Window * Quit(void) { +//This is crap. We need some REAL exit code, instead of this psuedo crap... !!! FIX !!! WriteLog("GUI: Quitting due to user request.\n"); - log_done(); + +// log_done(); + jaguar_done(); + version_done(); + memory_done(); + VideoDone(); // Free SDL components last...! + log_done(); + exit(0); return NULL; // We never get here... @@ -1324,6 +1590,29 @@ Window * About(void) return window; } +Window * MiscOptions(void) +{ + Window * window = new Window(8, 16, 304, 160); + window->AddElement(new PushButton(8, 8, &vjs.useJaguarBIOS, "BIOS")); + window->AddElement(new SlideSwitch(8, 20, &vjs.hardwareTypeNTSC, "PAL", "NTSC")); + window->AddElement(new PushButton(8, 40, &vjs.DSPEnabled, "DSP")); + window->AddElement(new SlideSwitch(16, 52, &vjs.usePipelinedDSP, "Original", "Pipelined")); + window->AddElement(new SlideSwitch(8, 72, (bool *)&vjs.glFilter, "Sharp", "Blurry")); + +// Missing: +// * BIOS path +// * ROM path +// * EEPROM path +// * joystick +// * joystick port +// * OpenGL? +// * GL Filter type +// * Window/fullscreen + + return window; +} + + // // Draw "picture" // Uses zero as transparent color @@ -1582,10 +1871,10 @@ uint32 JaguarLoadROM(uint8 * rom, char * path) // void JaguarLoadCart(uint8 * mem, char * path) { - uint32 romSize = JaguarLoadROM(mem, path); + jaguarRomSize = JaguarLoadROM(mem, path); - if (romSize == 0) - { +// if (romSize == 0) +// { /* char newPath[2048]; WriteLog("VJ: Trying GUI...\n"); @@ -1600,18 +1889,38 @@ void JaguarLoadCart(uint8 * mem, char * path) romSize = JaguarLoadROM(mem, newPath); */ - if (romSize == 0) + if (jaguarRomSize == 0) { // WriteLog("VJ: Could not load ROM from file \"%s\"...\nAborting!\n", newPath); WriteLog("VJ: Could not load ROM from file \"%s\"...\nAborting!\n", path); log_done(); exit(0); } - } +// } - jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romSize); + jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, jaguarRomSize); WriteLog("CRC: %08X\n", (unsigned int)jaguar_mainRom_crc32); eeprom_init(); + + jaguarRunAddress = 0x802000; +//NOTE: The bytes 'JAGR' should also be at position $1C... +// Also, there's *always* a $601A header at position $00... + if (jaguar_mainRom[0] == 0x60 && jaguar_mainRom[1] == 0x1A) + { + uint32 loadAddress = GET32(jaguar_mainRom, 0x22), runAddress = GET32(jaguar_mainRom, 0x2A); +//This is not always right! Especially when converted via bin2jag1!!! +//We should have access to the length of the furshlumiger file that was loaded anyway! +//Now, we do! ;-) +// uint32 progLength = GET32(jaguar_mainRom, 0x02); +//jaguarRomSize +//jaguarRunAddress +// WriteLog("Jaguar: Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, progLength); +// memcpy(jaguar_mainRam + loadAddress, jaguar_mainRom + 0x2E, progLength); + WriteLog("Jaguar: Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, jaguarRomSize - 0x2E); + memcpy(jaguar_mainRam + loadAddress, jaguar_mainRom + 0x2E, jaguarRomSize - 0x2E); +// SET32(jaguar_mainRam, 4, runAddress); + jaguarRunAddress = runAddress; + } } // diff --git a/src/include/jaguar.h b/src/include/jaguar.h index 4a1936f..c0fb46f 100644 --- a/src/include/jaguar.h +++ b/src/include/jaguar.h @@ -26,7 +26,7 @@ // Exports from JAGUAR.CPP extern int32 jaguar_cpu_in_exec; -extern uint32 jaguar_mainRom_crc32; +extern uint32 jaguar_mainRom_crc32, jaguarRomSize, jaguarRunAddress; extern char * jaguar_eeproms_path; extern char * whoName[9]; diff --git a/src/include/sdlemu_opengl.h b/src/include/sdlemu_opengl.h index c12ddc8..0f7e495 100644 --- a/src/include/sdlemu_opengl.h +++ b/src/include/sdlemu_opengl.h @@ -28,10 +28,10 @@ extern "C" { #endif -void sdlemu_init_opengl(SDL_Surface * src, int texturetype, int size, int glfilter); +void sdlemu_init_opengl(SDL_Surface * src, int texturetype, float size, int filter); void sdlemu_draw_texture(SDL_Surface * dst, SDL_Surface * src, int texturetype); void sdlemu_close_opengl(void); -void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst); +void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst, int filter); #ifdef __cplusplus } diff --git a/src/include/settings.h b/src/include/settings.h index 4ce5e1f..0a5fd23 100644 --- a/src/include/settings.h +++ b/src/include/settings.h @@ -20,9 +20,10 @@ struct VJSettings bool hardwareTypeNTSC; // Set to false for PAL bool useJaguarBIOS; bool DSPEnabled; + bool usePipelinedDSP; bool fullscreen; bool useOpenGL; - bool usePipelinedDSP; + uint32 glFilter; // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, * uint16 p1KeyBindings[21]; diff --git a/src/jaguar.cpp b/src/jaguar.cpp index 6dbb14e..af4718a 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -1,8 +1,8 @@ // // JAGUAR.CPP // -// by Cal2 -// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) +// Originally by David Raingeard (Cal2) +// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Carwin Jones (BeOS) // Cleanups and endian wrongness amelioration by James L. Hammons // Note: Endian wrongness probably stems from the MAME origins of this emu and // the braindead way in which MAME handles memory. :-) @@ -16,6 +16,7 @@ #define CPU_DEBUG //Do this in makefile??? Yes! Could, but it's easier to define here... #define LOG_UNMAPPED_MEMORY_ACCESSES +//#define ABORT_ON_UNMAPPED_MEMORY_ACCESS #define CPU_DEBUG_MEMORY // Private function prototypes @@ -42,7 +43,7 @@ char * whoName[9] = uint32 jaguar_active_memory_dumps = 0; -uint32 jaguar_mainRom_crc32; +uint32 jaguar_mainRom_crc32, jaguarRomSize, jaguarRunAddress; /*static*/ uint8 * jaguar_mainRam = NULL; /*static*/ uint8 * jaguar_bootRom = NULL; @@ -462,6 +463,8 @@ void jaguar_unknown_writebyte(unsigned address, unsigned data, uint32 who/*=UNKN { #ifdef LOG_UNMAPPED_MEMORY_ACCESSES WriteLog("Jaguar: Unknown byte %02X written at %08X by %s (M68K PC=%06X)\n", data, address, whoName[who], m68k_get_reg(NULL, M68K_REG_PC)); +#endif +#ifdef ABORT_ON_UNMAPPED_MEMORY_ACCESS extern bool finished; finished = true; extern bool doDSPDis; @@ -474,6 +477,8 @@ void jaguar_unknown_writeword(unsigned address, unsigned data, uint32 who/*=UNKN { #ifdef LOG_UNMAPPED_MEMORY_ACCESSES WriteLog("Jaguar: Unknown word %04X written at %08X by %s (M68K PC=%06X)\n", data, address, whoName[who], m68k_get_reg(NULL, M68K_REG_PC)); +#endif +#ifdef ABORT_ON_UNMAPPED_MEMORY_ACCESS extern bool finished; finished = true; extern bool doDSPDis; @@ -486,6 +491,8 @@ unsigned jaguar_unknown_readbyte(unsigned address, uint32 who/*=UNKNOWN*/) { #ifdef LOG_UNMAPPED_MEMORY_ACCESSES WriteLog("Jaguar: Unknown byte read at %08X by %s (M68K PC=%06X)\n", address, whoName[who], m68k_get_reg(NULL, M68K_REG_PC)); +#endif +#ifdef ABORT_ON_UNMAPPED_MEMORY_ACCESS extern bool finished; finished = true; extern bool doDSPDis; @@ -499,6 +506,8 @@ unsigned jaguar_unknown_readword(unsigned address, uint32 who/*=UNKNOWN*/) { #ifdef LOG_UNMAPPED_MEMORY_ACCESSES WriteLog("Jaguar: Unknown word read at %08X by %s (M68K PC=%06X)\n", address, whoName[who], m68k_get_reg(NULL, M68K_REG_PC)); +#endif +#ifdef ABORT_ON_UNMAPPED_MEMORY_ACCESS extern bool finished; finished = true; extern bool doDSPDis; @@ -816,17 +825,27 @@ void jaguar_reset(void) memcpy(jaguar_mainRam, jaguar_bootRom, 8); else { - SET32(jaguar_mainRam, 4, 0x00802000); +// Should also make a run address global as well, for when we reset the jag (PD mainly) +/* SET32(jaguar_mainRam, 4, 0x00802000); // Handle PD stuff... // This should definitely go elsewhere (like in the cart load section)! +//NOTE: The bytes 'JAGR' should also be at position $1C... if (jaguar_mainRom[0] == 0x60 && jaguar_mainRom[1] == 0x1A) { - uint32 runAddress = GET32(jaguar_mainRom, 0x2A); - uint32 progLength = GET32(jaguar_mainRom, 0x02); - WriteLog("Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, progLength); - memcpy(jaguar_mainRam + runAddress, jaguar_mainRom + 0x2E, progLength); + uint32 loadAddress = GET32(jaguar_mainRom, 0x22), runAddress = GET32(jaguar_mainRom, 0x2A); +//This is not always right! Especially when converted via bin2jag1!!! +//We should have access to the length of the furshlumiger file that was loaded anyway! +//Now, we do! ;-) +// uint32 progLength = GET32(jaguar_mainRom, 0x02); +//jaguarRomSize +//jaguarRunAddress +// WriteLog("Jaguar: Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, progLength); +// memcpy(jaguar_mainRam + loadAddress, jaguar_mainRom + 0x2E, progLength); + WriteLog("Jaguar: Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, jaguarRomSize - 0x2E); + memcpy(jaguar_mainRam + loadAddress, jaguar_mainRom + 0x2E, jaguarRomSize - 0x2E); SET32(jaguar_mainRam, 4, runAddress); - } + }//*/ + SET32(jaguar_mainRam, 4, jaguarRunAddress); } // WriteLog("jaguar_reset():\n"); @@ -895,23 +914,23 @@ if (effect_start) // if (invalid_instruction_address != 0x80000000) // cd_bios_process(invalid_instruction_address); //if (start_logging) -// WriteLog("About to execute M68K...\n"); +// WriteLog("About to execute M68K (%u)...\n", i); m68k_execute(M68KCyclesPerScanline); // No CD handling... !!! FIX !!! //if (start_logging) -// WriteLog("About to execute CD BIOS...\n"); +// WriteLog("About to execute CD BIOS (%u)...\n", i); cd_bios_exec(i); // NOTE: Ignores parameter... //if (start_logging) -// WriteLog("About to execute TOM's PIT...\n"); +// WriteLog("About to execute TOM's PIT (%u)...\n", i); TOMExecPIT(RISCCyclesPerScanline); //if (start_logging) -// WriteLog("About to execute JERRY's PIT...\n"); +// WriteLog("About to execute JERRY's PIT (%u)...\n", i); jerry_pit_exec(RISCCyclesPerScanline); //if (start_logging) -// WriteLog("About to execute JERRY's SSI...\n"); +// WriteLog("About to execute JERRY's SSI (%u)...\n", i); jerry_i2s_exec(RISCCyclesPerScanline); //if (start_logging) -// WriteLog("About to execute GPU...\n"); +// WriteLog("About to execute GPU (%u)...\n", i); gpu_exec(RISCCyclesPerScanline); if (vjs.DSPEnabled) @@ -922,7 +941,7 @@ if (effect_start) // DSPExecComp(RISCCyclesPerScanline); // Comparison core //if (start_logging) -// WriteLog("About to execute OP...\n"); +// WriteLog("About to execute OP (%u)...\n", i); TOMExecScanline(i, render); } } diff --git a/src/objectp.cpp b/src/objectp.cpp index ec468c9..8237471 100644 --- a/src/objectp.cpp +++ b/src/objectp.cpp @@ -316,6 +316,9 @@ extern int op_start_log; // objectp_stop_reading_list = false; +//WriteLog("OP: Processing line #%u (OLP=%08X)...\n", scanline, op_pointer); +//op_done(); + // *** BEGIN OP PROCESSOR TESTING ONLY *** extern bool interactiveMode; extern bool iToggle; @@ -337,6 +340,7 @@ else // return; uint64 p0 = op_load_phrase(op_pointer); +//WriteLog("\t%08X type %i\n", op_pointer, (uint8)p0 & 0x07); op_pointer += 8; if (scanline == tom_get_vdb() && op_start_log) //if (scanline == 215 && op_start_log) @@ -406,7 +410,6 @@ if ((p0 & 0x07) == OBJECT_TYPE_STOP) WriteLog(" --> List end\n"); }//*/ -// WriteLog("%08X type %i\n", op_pointer, (uint8)p0 & 0x07); switch ((uint8)p0 & 0x07) { case OBJECT_TYPE_BITMAP: @@ -465,7 +468,14 @@ if (!inhibit) // For OP testing only! p0 |= data << 40; OPStorePhrase(oldOPP, p0); } +//WriteLog("\t\tOld OP: %08X -> ", op_pointer); +//Temp, for testing... +//No doubt, this type of check will break all kinds of stuff... !!! FIX !!! + if (op_pointer > ((p0 & 0x000007FFFF000000LL) >> 21)) + return; + op_pointer = (p0 & 0x000007FFFF000000LL) >> 21; +//WriteLog("New OP: %08X\n", op_pointer); break; } case OBJECT_TYPE_SCALE: @@ -506,12 +516,14 @@ if (!inhibit) // For OP testing only! if (vscale == 0) vscale = 0x20; // OP bug??? Nope, it isn't...! Or is it? -/*extern int start_logging; -if (start_logging) - WriteLog("--> Returned from scaled bitmap processing (rem=%02X, vscale=%02X)...\n", remainder, vscale);*/ +//extern int start_logging; +//if (start_logging) +// WriteLog("--> Returned from scaled bitmap processing (rem=%02X, vscale=%02X)...\n", remainder, vscale);//*/ //Locks up here: //--> Returned from scaled bitmap processing (rem=20, vscale=80)... //There are other problems here, it looks like... +//Another lock up: +//About to execute OP (508)... /* OP: Scaled bitmap 4x? 4bpp at 38,? hscale=7C fpix=0 data=00075E28 pitch 1 hflipped=no dwidth=? (linked to 00071118) Transluency=no --> Returned from scaled bitmap processing (rem=50, vscale=7C)... @@ -576,8 +588,8 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp remainder -= 0x20; // 1.0f in [3.5] fixed point format -/*if (start_logging) - WriteLog("--> Finished writebacks...\n");*/ +//if (start_logging) +// WriteLog("--> Finished writebacks...\n");//*/ //WriteLog(" [%08X%08X -> ", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); p2 &= ~0x0000000000FF0000LL; diff --git a/src/sdlemu_opengl.c b/src/sdlemu_opengl.c index 2553785..6b92f18 100644 --- a/src/sdlemu_opengl.c +++ b/src/sdlemu_opengl.c @@ -22,6 +22,7 @@ static SDL_Surface *texture = 0; static GLuint texid = 0; static GLfloat texcoord[4]; +static unsigned int glFilter; static inline int power_of_two(int input) { @@ -33,16 +34,16 @@ static inline int power_of_two(int input) return value; } -void sdlemu_init_opengl(SDL_Surface * src, int texturetype, int size, int glfilter) +void sdlemu_init_opengl(SDL_Surface * src, int texturetype, float size, int filter) { int w, h; printf("\nOpenGL driver information :\n"); printf("\n"); - printf("Vendor : %s\n", glGetString(GL_VENDOR)); - printf("Renderer : %s\n", glGetString(GL_RENDERER)); - printf("Version : %s\n", glGetString(GL_VERSION)); - printf("OpenGL drawmethod : "); + printf("Vendor: %s\n", glGetString(GL_VENDOR)); + printf("Renderer: %s\n", glGetString(GL_RENDERER)); + printf("Version: %s\n", glGetString(GL_VERSION)); + printf("OpenGL drawmethod: "); switch (texturetype) { @@ -54,6 +55,8 @@ void sdlemu_init_opengl(SDL_Surface * src, int texturetype, int size, int glfilt break; } + glFilter = filter; + // Texture width/height should be power of 2 // So, find the largest power of two that will contain both the width and height w = power_of_two(src->w); @@ -94,15 +97,15 @@ void sdlemu_init_opengl(SDL_Surface * src, int texturetype, int size, int glfilt glGenTextures(1, &texid); glBindTexture(GL_TEXTURE_2D, texid); - if (glfilter) + if (glFilter) { - printf("OpenGL filters : enabled\n"); + printf("OpenGL filters: enabled\n"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { - printf("OpenGL filters : disabled\n"); + printf("OpenGL filters: disabled\n"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } @@ -158,8 +161,9 @@ void sdlemu_close_opengl(void) // Resize the texture // This should honor the glFilter flag that is passed in to the initialization code, // but, at the moment, it doesn't... +// Now it does...! // -void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst) +void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst, int filter) { // Texture width/height should be power of 2 // So, find the largest power of two that will contain both the width and height @@ -204,15 +208,16 @@ void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst) glGenTextures(1, &texid); glBindTexture(GL_TEXTURE_2D, texid); -/* if (glfilter) +// if (glFilter) + if (filter) { - printf("OpenGL filters : enabled\n"); + printf("OpenGL filters: enabled\n"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - else*/ + else { - printf("OpenGL filters : disabled\n"); + printf("OpenGL filters: disabled\n"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } diff --git a/src/settings.cpp b/src/settings.cpp index 91645b0..a0d5746 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -34,9 +34,10 @@ void LoadVJSettings(void) vjs.hardwareTypeNTSC = sdlemu_getval_bool("hardwareTypeNTSC", true); vjs.useJaguarBIOS = sdlemu_getval_bool("useJaguarBIOS", false); vjs.DSPEnabled = sdlemu_getval_bool("DSPEnabled", false); + vjs.usePipelinedDSP = sdlemu_getval_bool("usePipelinedDSP", true); vjs.fullscreen = sdlemu_getval_bool("fullscreen", false); vjs.useOpenGL = sdlemu_getval_bool("useOpenGL", true); - vjs.usePipelinedDSP = sdlemu_getval_bool("usePipelinedDSP", true); + vjs.glFilter = sdlemu_getval_int("glFilterType", 0); // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, * vjs.p1KeyBindings[0] = sdlemu_getval_int("p1k_up", SDLK_UP); diff --git a/src/video.cpp b/src/video.cpp index 601fc30..cd214e0 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -81,7 +81,8 @@ bool InitVideo(void) } if (vjs.useOpenGL) - sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, 0/*texture type (linear, nearest)*/); +//Should make another setting here, for either linear or nearest (instead of just picking one) + sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, vjs.glFilter/*texture type (linear, nearest)*/); // Initialize Joystick support under SDL if (vjs.useJoystick) @@ -169,9 +170,10 @@ void ResizeScreen(uint32 width, uint32 height) exit(1); } - sprintf(window_title, "Virtual Jaguar (%i x %i)", (int)width, (int)height); - - if (!vjs.useOpenGL) + if (vjs.useOpenGL) + // This seems to work well for resizing (i.e., changes in the pixel width)... + sdlemu_resize_texture(surface, mainSurface, vjs.glFilter); + else { mainSurface = SDL_SetVideoMode(width, height, 16, mainSurfaceFlags); @@ -182,11 +184,12 @@ void ResizeScreen(uint32 width, uint32 height) } } + sprintf(window_title, "Virtual Jaguar (%i x %i)", (int)width, (int)height); SDL_WM_SetCaption(window_title, window_title); // This seems to work well for resizing (i.e., changes in the pixel width)... - if (vjs.useOpenGL) - sdlemu_resize_texture(surface, mainSurface); +// if (vjs.useOpenGL) +// sdlemu_resize_texture(surface, mainSurface); } // diff --git a/src/vj.cpp b/src/vj.cpp index c256bfd..effc91d 100644 --- a/src/vj.cpp +++ b/src/vj.cpp @@ -181,7 +181,9 @@ int main(int argc, char * argv[]) jaguar_init(); // Get the BIOS ROM - if (vjs.useJaguarBIOS) +// if (vjs.useJaguarBIOS) +// What would be nice here would be a way to check if the BIOS was loaded so that we +// could disable the pushbutton on the Misc Options menu... !!! FIX !!! JaguarLoadROM(jaguar_bootRom, vjs.jagBootPath); SET32(jaguar_mainRam, 0, 0x00200000); // Set top of stack...