X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fgui%2Fgui.cpp;h=95e019238efa7f57ea902fa460d8c5a34cb5c4d4;hb=dd520b965a1e6531bd1d285494b223ab04c5368b;hp=a8805c9e5f226ed2545ca0e590dd0e84d9b72454;hpb=836c7fa1f3e2dc3ec9849cac2584d4544bf2fba4;p=virtualjaguar diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index a8805c9..95e0192 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -7,19 +7,9 @@ #include "gui.h" -#include -#include // For toupper() #include -#include -#include // For MacOS dependency -#include -#include #include "crc32.h" -#include "event.h" #include "file.h" -#include "font1.h" -#include "font14pt.h" // Also 15, 16, 17, 18 -#include "guielements.h" #include "jaguar.h" #include "log.h" #include "sdlemu_opengl.h" @@ -27,23 +17,22 @@ #include "tom.h" #include "video.h" -using namespace std; // For STL stuff +// Once these are split off, these may not be needed anymore... +#include "button.h" +#include "element.h" +#include "filelist.h" +#include "guimisc.h" +#include "image.h" +#include "listbox.h" +#include "menu.h" +#include "pushbutton.h" +#include "slideswitch.h" +#include "text.h" +#include "textedit.h" +#include "window.h" // Private function prototypes -class Window; // Forward declaration... - -//void DrawTransparentBitmap(uint32 * screen, uint32 x, uint32 y, uint32 * bitmap, uint8 * alpha = NULL); -void DrawTransparentBitmapDeprecated(uint32 * screen, uint32 x, uint32 y, uint32 * bitmap); -void DrawTransparentBitmap(uint32 * screen, uint32 x, uint32 y, const void * bitmap); -void DrawBitmap(uint32 * screen, uint32 x, uint32 y, const void * bitmap); -//Should call this FillScreenRectangle with a number representing the RGBA value to fill. !!! FIX !!! -//void ClearScreenRectangle(uint32 * screen, uint32 x, uint32 y, uint32 w, uint32 h); -void FillScreenRectangle(uint32 * screen, uint32 x, uint32 y, uint32 w, uint32 h, uint32 color); -void DrawStringTrans(uint32 * screen, uint32 x, uint32 y, uint32 color, uint8 opacity, const char * text, ...); -void DrawStringOpaque(uint32 * screen, uint32 x, uint32 y, uint32 color1, uint32 color2, const char * text, ...); -void DrawString(uint32 * screen, uint32 x, uint32 y, bool invert, const char * text, ...); -void DrawString2(uint32 * screen, uint32 x, uint32 y, uint32 color, uint8 transparency, const char * text, ...); Window * LoadROM(void); Window * ResetJaguar(void); Window * ResetJaguarCD(void); @@ -63,1549 +52,6 @@ bool showMessage = false; //char messageBuffer[200]; bool finished = false; -const char separator[] = "--------------------------------------------------------"; - -// -// Case insensitive string compare function -// Taken straight out of Thinking In C++ by Bruce Eckel. Thanks Bruce! -// - -int stringCmpi(const string &s1, const string &s2) -{ - // Select the first element of each string: - string::const_iterator p1 = s1.begin(), p2 = s2.begin(); - - while (p1 != s1.end() && p2 != s2.end()) // Don�t run past the end - { - if (toupper(*p1) != toupper(*p2)) // Compare upper-cased chars - return (toupper(*p1) < toupper(*p2) ? -1 : 1);// Report which was lexically greater - - p1++; - p2++; - } - - // If they match up to the detected eos, say which was longer. Return 0 if the same. - return s2.size() - s1.size(); -} - -// -// Local GUI classes -// - -enum { WINDOW_CLOSE, MENU_ITEM_CHOSEN }; - -class Element -{ - public: - Element(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0) - { extents.x = x, extents.y = y, extents.w = w, extents.h = h; } - virtual void HandleKey(SDLKey key) = 0; // These are "pure" virtual functions... - virtual void HandleMouseMove(uint32 x, uint32 y) = 0; - virtual void HandleMouseButton(uint32 x, uint32 y, bool mouseDown) = 0; - virtual void Draw(uint32, uint32) = 0; - virtual void Notify(Element *) = 0; -//Needed? virtual ~Element() = 0; -//We're not allocating anything in the base class, so the answer would be NO. - bool Inside(uint32 x, uint32 y); - // Class method -// static void SetScreenAndPitch(int16 * s, uint32 p) { screenBuffer = s, pitch = p; } - static void SetScreenAndPitch(uint32 * s, uint32 p) { screenBuffer = s, pitch = p; } - - protected: - SDL_Rect extents; - uint32 state; - // Class variables... -// static int16 * screenBuffer; - static uint32 * screenBuffer; - static uint32 pitch; -}; - -// Initialize class variables (Element) -//int16 * Element::screenBuffer = NULL; -uint32 * Element::screenBuffer = NULL; -uint32 Element::pitch = 0; - -bool Element::Inside(uint32 x, uint32 y) -{ - return (x >= (uint32)extents.x && x < (uint32)(extents.x + extents.w) - && y >= (uint32)extents.y && y < (uint32)(extents.y + extents.h) ? true : false); -} - - -// -// Button class -// - -class Button: public Element -{ - public: - Button(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0): Element(x, y, w, h), - activated(false), clicked(false), inside(false), fgColor(0xFFFFFFFF), - bgColor(0xFF00FF00), pic(NULL), elementToTell(NULL) {} - Button(uint32 x, uint32 y, uint32 w, uint32 h, uint32 * p): Element(x, y, w, h), - activated(false), clicked(false), inside(false), fgColor(0xFFFFFFFF), - bgColor(0xFF00FF00), pic(p), elementToTell(NULL) {} -// Button(uint32 x, uint32 y, uint32 * p): Element(x, y, 0, 0), - Button(uint32 x, uint32 y, uint32 * p, uint32 * pH = NULL, uint32 * pD = NULL): Element(x, y, 0, 0), - activated(false), clicked(false), inside(false), fgColor(0xFFFFFFFF), - bgColor(0xFF00FF00), pic(p), picHover(pH), picDown(pD), 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(0xFFFFFFFF), - bgColor(0xFF00FF00), pic(NULL), text(s), elementToTell(NULL) {} - Button(uint32 x, uint32 y, string s): Element(x, y, 0, FONT_HEIGHT), - activated(false), clicked(false), inside(false), fgColor(0xFFFFFFFF), - bgColor(0xFF00FF00), pic(NULL), text(s), elementToTell(NULL) - { extents.w = s.length() * FONT_WIDTH; } - 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 activated, clicked, inside; - uint32 fgColor, bgColor; - uint32 * pic, * picHover, * picDown; - string text; - Element * elementToTell; -}; - -void Button::HandleMouseMove(uint32 x, uint32 y) -{ - inside = Inside(x, y); -} - -void Button::HandleMouseButton(uint32 x, uint32 y, bool mouseDown) -{ - if (inside) - { - 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); - } - } - else - clicked = activated = false; -} - -void Button::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) -{ - uint32 addr = (extents.x + offsetX) + ((extents.y + offsetY) * pitch); - - if (text.length() > 0) // Simple text button -// if (pic == NULL) - { - for(uint32 y=0; y 010000 11111 10000 -> 0100 0001 1111 1111 1000 0100 -> 41 FF 84 - = (clicked && inside ? fgColor : (inside ? 0xFF84FF41 : bgColor)); - } - } - - DrawString(screenBuffer, extents.x + offsetX, extents.y + offsetY, false, "%s", text.c_str()); - } - else // Graphical button - { - uint32 * picToShow = pic; - - if (picHover != NULL && inside && !clicked) - picToShow = picHover; - - if (picDown != NULL && inside && clicked) - picToShow = picDown; - - DrawTransparentBitmapDeprecated(screenBuffer, extents.x + offsetX, extents.y + offsetY, picToShow); - } -} - - -// -// PushButton class -// - -class PushButton: public Element -{ -// How to handle? -// Save state externally? -//We pass in a state variable if we want to track it externally, otherwise we use our own -//internal state var. Still need to do some kind of callback for pushbuttons that do things -//like change from fullscreen to windowed... !!! FIX !!! - - 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; } - PushButton(uint32 x, uint32 y, bool * st, string s): Element(x, y, 16, 16), state(st), - inside(false), text(s) { if (st == NULL) state = &internalState; } -/* Button(uint32 x, uint32 y, uint32 w, uint32 h, uint32 * 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, uint32 * 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; -// uint32 * 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 + 24, extents.y + offsetY, false, "%s", text.c_str()); -} - - -// -// SlideSwitch class -// - -class SlideSwitch: public Element -{ -// How to handle? -// Save state externally? -//Seems to be handled the same as PushButton, but without sanity checks. !!! FIX !!! - - public: - SlideSwitch(uint32 x, uint32 y, bool * st, string s1, string s2): Element(x, y, 16, 32), 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; -// uint32 * 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*/) -{ - DrawTransparentBitmapDeprecated(screenBuffer, extents.x + offsetX, extents.y + offsetY, (*state ? slideSwitchDown : slideSwitchUp)); - - if (text1.length() > 0) - DrawString(screenBuffer, extents.x + offsetX + 24, extents.y + offsetY, false, "%s", text1.c_str()); - - if (text2.length() > 0) - DrawString(screenBuffer, extents.x + offsetX + 24, extents.y + offsetY + 16, false, "%s", text2.c_str()); -} - - -// -// Window class -// - -class Window: public Element -{ - public: -/* Window(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0): Element(x, y, w, h), - fgColor(0x4FF0), bgColor(0xFE10) - { close = new Button(w - 8, 1, closeBox); list.push_back(close); }*/ - Window(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0, - void (* f)(Element *) = NULL): Element(x, y, w, h), -// /*clicked(false), inside(false),*/ fgColor(0x4FF0), bgColor(0x1E10), -//4FF0 -> 010011 11111 10000 -> 0100 1101 1111 1111 1000 0100 -> 4D FF 84 -//1E10 -> 000111 10000 10000 -> 0001 1111 1000 0100 1000 0100 -> 1F 84 84 - /*clicked(false), inside(false),*/ fgColor(0xFF84FF4D), bgColor(0xFF84841F), - handler(f) - { close = new Button(w - (CLOSEBOX_WIDTH + 1), 1, closeBox, closeBoxHover, closeBoxDown); - list.push_back(close); - close->SetNotificationElement(this); } - virtual ~Window(); - 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 * e); - void AddElement(Element * e); -// bool WindowActive(void) { return true; }//return !close->ButtonClicked(); } - - protected: -// bool clicked, inside; - uint32 fgColor, bgColor; - void (* handler)(Element *); - Button * close; -//We have to use a list of Element *pointers* because we can't make a list that will hold -//all the different object types in the same list... - vector list; -}; - -Window::~Window() -{ - for(uint32 i=0; iHandleKey(key); -} - -void Window::HandleMouseMove(uint32 x, uint32 y) -{ - // Handle the items this window contains... - for(uint32 i=0; iHandleMouseMove(x - extents.x, y - extents.y); -} - -void Window::HandleMouseButton(uint32 x, uint32 y, bool mouseDown) -{ - // Handle the items this window contains... - for(uint32 i=0; iHandleMouseButton(x - extents.x, y - extents.y, mouseDown); -} - -void Window::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) -{ - uint32 addr = (extents.x + offsetX) + ((extents.y + offsetY) * pitch); - - for(uint32 y=0; yDraw(extents.x, extents.y); -} - -void Window::AddElement(Element * e) -{ - list.push_back(e); -} - -void Window::Notify(Element * e) -{ - if (e == close) - { - SDL_Event event; - event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE; - SDL_PushEvent(&event); - } -} - - -// -// Static text class -// - -class Text: public Element -{ - public: -// Text(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0): Element(x, y, w, h), -// fgColor(0x4FF0), bgColor(0xFE10) {} -// Text(uint32 x, uint32 y, string s, uint16 fg = 0x4FF0, uint16 bg = 0xFE10): Element(x, y, 0, 0), -// fgColor(fg), bgColor(bg), text(s) {} -//4FF0 -> 010011 11111 10000 -> 0100 1101 1111 1111 1000 0100 -> 4D FF 84 -//FE10 -> 111111 10000 10000 -> 1111 1111 1000 0100 1000 0100 -> FF 84 84 - Text(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0): Element(x, y, w, h), - fgColor(0xFF8484FF), bgColor(0xFF84FF4D) {} - Text(uint32 x, uint32 y, string s, uint32 fg = 0xFF8484FF, uint32 bg = 0xFF84FF4D): - Element(x, y, 0, 0), fgColor(fg), bgColor(bg), text(s) {} - 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 *) {} - - protected: - uint32 fgColor, bgColor; - string text; -}; - -void Text::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) -{ - if (text.length() > 0) -// DrawString(screenBuffer, extents.x + offsetX, extents.y + offsetY, false, "%s", text.c_str()); - DrawStringOpaque(screenBuffer, extents.x + offsetX, extents.y + offsetY, fgColor, bgColor, "%s", text.c_str()); -} - - -// -// Static image class -// - -class Image: public Element -{ - public: - Image(uint32 x, uint32 y, const void * img): Element(x, y, 0, 0), image(img) {} - 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 *) {} - - protected: - uint32 fgColor, bgColor; - const void * image; -}; - -void Image::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) -{ - if (image != NULL) - DrawTransparentBitmap(screenBuffer, extents.x + offsetX, extents.y + offsetY, image); -} - - -// -// TextEdit class -// - -class TextEdit: public Element -{ - public: - TextEdit(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0): Element(x, y, w, h), - fgColor(0xFF8484FF), bgColor(0xFF84FF4D), text(""), caretPos(0), - maxScreenSize(10) {} - TextEdit(uint32 x, uint32 y, string s, uint32 mss = 10, uint32 fg = 0xFF8484FF, - uint32 bg = 0xFF84FF4D): Element(x, y, 0, 0), fgColor(fg), bgColor(bg), text(s), - caretPos(0), maxScreenSize(mss) {} - 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 *) {} - - protected: - uint32 fgColor, bgColor; - string text; - uint32 caretPos; - uint32 maxScreenSize; -}; - -//Set different filters depending on type passed in on construction, e.g., filename, amount, etc...? -void TextEdit::HandleKey(SDLKey key) -{ - if ((key >= SDLK_a && key <= SDLK_z) || (key >= SDLK_0 && key <= SDLK_9) || key == SDLK_PERIOD - || key == SDLK_SLASH) - { - //Need to handle shift key as well... - text[caretPos++] = key; - Draw(); - } - else if (key == SDLK_BACKSPACE) - { - - } - else if (key == SDLK_DELETE) - { - } -//left, right arrow -} - -void TextEdit::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) -{ - if (text.length() > 0) - { - FillScreenRectangle(screenBuffer, extents.x + offsetX, extents.y + offsetY, FONT_WIDTH * maxScreenSize, FONT_HEIGHT, bgColor); -// DrawString(screenBuffer, extents.x + offsetX, extents.y + offsetY, false, "%s", text.c_str()); - DrawStringOpaque(screenBuffer, extents.x + offsetX, extents.y + offsetY, fgColor, bgColor, "%s", text.c_str()); - } - - // Draw the caret (underscore? or vertical line?) -} - - -// -// ListBox class -// - -class ListBox: public Element -//class ListBox: public Window -{ - public: -// ListBox(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0): Element(x, y, w, h), - ListBox(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0);//: Window(x, y, w, h), -// windowPtr(0), cursor(0), limit(0), charWidth((w / 8) - 1), charHeight(h / 8), -// elementToTell(NULL), upArrow(w - 8, 0, upArrowBox), -// downArrow(w - 8, h - 8, downArrowBox), upArrow2(w - 8, h - 16, upArrowBox) {} - 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 * e); - void SetNotificationElement(Element * e) { elementToTell = e; } - void AddItem(string s); - string GetSelectedItem(void); - - protected: - bool thumbClicked; - uint32 windowPtr, cursor, limit; - uint32 charWidth, charHeight; // Box width/height in characters - Element * elementToTell; - Button upArrow, downArrow, upArrow2; - vector item; - - private: - uint32 yRelativePoint; -}; - -ListBox::ListBox(uint32 x, uint32 y, uint32 w, uint32 h): Element(x, y, w, h), - thumbClicked(false), windowPtr(0), cursor(0), limit(0), charWidth((w / FONT_WIDTH) - 1), - charHeight(h / FONT_HEIGHT), elementToTell(NULL), upArrow(w - 8, 0, upArrowBox), - downArrow(w - 8, h - 8, downArrowBox), upArrow2(w - 8, h - 16, upArrowBox) -{ - upArrow.SetNotificationElement(this); - downArrow.SetNotificationElement(this); - upArrow2.SetNotificationElement(this); - extents.w -= 8; // Make room for scrollbar... -} - -void ListBox::HandleKey(SDLKey key) -{ - if (key == SDLK_DOWN) - { - if (cursor != limit - 1) // Cursor is within its window - cursor++; - else // Otherwise, scroll the window... - { - if (cursor + windowPtr != item.size() - 1) - windowPtr++; - } - } - else if (key == SDLK_UP) - { - if (cursor != 0) - cursor--; - else - { - if (windowPtr != 0) - windowPtr--; - } - } - else if (key == SDLK_PAGEDOWN) - { - if (cursor != limit - 1) - cursor = limit - 1; - else - { - windowPtr += limit; - if (windowPtr > item.size() - limit) - windowPtr = item.size() - limit; - } - } - else if (key == SDLK_PAGEUP) - { - if (cursor != 0) - cursor = 0; - else - { - if (windowPtr < limit) - windowPtr = 0; - else - windowPtr -= limit; - } - } - else if (key >= SDLK_a && key <= SDLK_z) - { - // Advance cursor to filename with first letter pressed... - uint8 which = (key - SDLK_a) + 65; // Convert key to A-Z char - - for(uint32 i=0; i windowPtr + limit - 1) - windowPtr = i - limit + 1, cursor = limit - 1; - if (i < windowPtr) - windowPtr = i, cursor = 0; - break; - } - } - } -} - -void ListBox::HandleMouseMove(uint32 x, uint32 y) -{ - upArrow.HandleMouseMove(x - extents.x, y - extents.y); - downArrow.HandleMouseMove(x - extents.x, y - extents.y); - upArrow2.HandleMouseMove(x - extents.x, y - extents.y); - - if (thumbClicked) - { - uint32 sbHeight = extents.h - 24, - thumb = (uint32)(((float)limit / (float)item.size()) * (float)sbHeight); - -//yRelativePoint is the spot on the thumb where we clicked... - int32 newThumbStart = y - yRelativePoint; - - if (newThumbStart < 0) - newThumbStart = 0; - - if ((uint32)newThumbStart > sbHeight - thumb) - newThumbStart = sbHeight - thumb; - - windowPtr = (uint32)(((float)newThumbStart / (float)sbHeight) * (float)item.size()); -//Check for cursor bounds as well... Or do we need to??? -//Actually, we don't...! - } -} - -void ListBox::HandleMouseButton(uint32 x, uint32 y, bool mouseDown) -{ - if (Inside(x, y) && mouseDown) - { - // Why do we have to do this??? (- extents.y?) - // I guess it's because only the Window class has offsetting implemented... !!! FIX !!! -// cursor = (y - extents.y) / 8; - cursor = (y - extents.y) / FONT_HEIGHT; - } - - // Check for a hit on the scrollbar... - if (x > (uint32)(extents.x + extents.w) && x <= (uint32)(extents.x + extents.w + 8) - && y > (uint32)(extents.y + 8) && y <= (uint32)(extents.y + extents.h - 16)) - { - if (mouseDown) - { -// This shiaut should be calculated in AddItem(), not here... (or in Draw() for that matter) - uint32 sbHeight = extents.h - 24, - thumb = (uint32)(((float)limit / (float)item.size()) * (float)sbHeight), - thumbStart = (uint32)(((float)windowPtr / (float)item.size()) * (float)sbHeight); - - // Did we hit the thumb? - if (y >= (extents.y + 8 + thumbStart) && y < (extents.y + 8 + thumbStart + thumb)) - thumbClicked = true, yRelativePoint = y - thumbStart; - } -//Seems that this is useless--never reached except in rare cases and that the code outside is -//more effective... -// else -// thumbClicked = false; - } - - if (!mouseDown) - thumbClicked = false; - - upArrow.HandleMouseButton(x - extents.x, y - extents.y, mouseDown); - downArrow.HandleMouseButton(x - extents.x, y - extents.y, mouseDown); - upArrow2.HandleMouseButton(x - extents.x, y - extents.y, mouseDown); -} - -void ListBox::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) -{ - for(uint32 i=0; i= thumbStart + (extents.y+offsetY+8) && y < thumbStart + thumb + (extents.y+offsetY+8)) -// screenBuffer[x + (y * pitch)] = (thumbClicked ? 0x458E : 0xFFFF); -//458E -> 01 0001 0 1100 0 1110 -> 0100 0101 0110 0011 0111 0011 -> 45 63 73 - screenBuffer[x + (y * pitch)] = (thumbClicked ? 0xFF736345 : 0xFFFFFFFF); - else -// screenBuffer[x + (y * pitch)] = 0x0200; -//0200 -> 000000 10000 00000 -> 00 1000 0100 00 - screenBuffer[x + (y * pitch)] = 0xFF008400; - } - } -} - -void ListBox::Notify(Element * e) -{ - if (e == &upArrow || e == &upArrow2) - { - if (windowPtr != 0) - { - windowPtr--; - - if (cursor < limit - 1) - cursor++; - } - } - else if (e == &downArrow) - { - if (windowPtr < item.size() - limit) - { - windowPtr++; - - if (cursor != 0) - cursor--; - } - } -} - -void ListBox::AddItem(string s) -{ - // Do a simple insertion sort - bool inserted = false; - - for(vector::iterator i=item.begin(); i charHeight ? charHeight : item.size()); -} - -string ListBox::GetSelectedItem(void) -{ - return item[windowPtr + cursor]; -} - - -// -// FileList class -// - -class FileList: public Window -{ - public: - FileList(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = 0); - virtual ~FileList() {} - virtual void HandleKey(SDLKey key); - virtual void HandleMouseMove(uint32 x, uint32 y) { Window::HandleMouseMove(x, y); } - virtual void HandleMouseButton(uint32 x, uint32 y, bool mouseDown) { Window::HandleMouseButton(x, y, mouseDown); } - virtual void Draw(uint32 offsetX = 0, uint32 offsetY = 0) { Window::Draw(offsetX, offsetY); } - virtual void Notify(Element * e); - - protected: - ListBox * files; - Button * load; -}; - -//Need 4 buttons, one scrollbar... -FileList::FileList(uint32 x, uint32 y, uint32 w, uint32 h): Window(x, y, w, h) -{ - files = new ListBox(8, 8, w - 16, h - 32); - AddElement(files); - load = new Button(8, h - 16, " Load "); - AddElement(load); - load->SetNotificationElement(this); - -#warning !!! FIX !!! Directory might not exist--this shouldn't cause VJ to crash! - DIR * dp = opendir(vjs.ROMPath); - dirent * de; - - if (dp != NULL) - { - while ((de = readdir(dp)) != NULL) - { - char * ext = strrchr(de->d_name, '.'); - - if (ext != NULL) - if (strcasecmp(ext, ".zip") == 0 || strcasecmp(ext, ".j64") == 0 - || strcasecmp(ext, ".abs") == 0 || strcasecmp(ext, ".jag") == 0 - || strcasecmp(ext, ".rom") == 0) - files->AddItem(string(de->d_name)); - } - - closedir(dp); - } - else - { -//Give a diagnostic message here so that the (l)user can figure out what went wrong. !!! FIX !!! - } -} - -void FileList::HandleKey(SDLKey key) -{ - if (key == SDLK_RETURN) - Notify(load); - else - Window::HandleKey(key); -} - -void FileList::Notify(Element * e) -{ - if (e == load) - { - char filename[MAX_PATH]; - strcpy(filename, vjs.ROMPath); - - if (strlen(filename) > 0) - if (filename[strlen(filename) - 1] != '/') - strcat(filename, "/"); - - strcat(filename, files->GetSelectedItem().c_str()); - -// uint32 romSize = JaguarLoadROM(jaguar_mainRom, filename); -// JaguarLoadCart(jaguar_mainRom, filename); - if (JaguarLoadFile(filename)) - { - SDL_Event event; - event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE; - SDL_PushEvent(&event); - - event.type = SDL_USEREVENT, event.user.code = MENU_ITEM_CHOSEN; - event.user.data1 = (void *)ResetJaguar; - SDL_PushEvent(&event); - } - else - { - SDL_Event event; - event.type = SDL_USEREVENT, event.user.code = WINDOW_CLOSE; - SDL_PushEvent(&event); - - // Handle the error, but don't run... - // Tell the user that we couldn't run their file for some reason... !!! FIX !!! -//how to kludge: Make a function like ResetJaguar which creates the dialog window - } - } - else - Window::Notify(e); -} - - -// -// Menu class & supporting structs/classes -// - -struct NameAction -{ - string name; - Window * (* action)(void); - SDLKey hotKey; - - NameAction(string n, Window * (* a)(void) = NULL, SDLKey k = SDLK_UNKNOWN): name(n), - action(a), hotKey(k) {} -}; - -class MenuItems -{ - public: - MenuItems(): charLength(0) {} - bool Inside(uint32 x, uint32 y) - { return (x >= (uint32)extents.x && x < (uint32)(extents.x + extents.w) - && y >= (uint32)extents.y && y < (uint32)(extents.y + extents.h) ? true : false); } - - string title; - vector item; - uint32 charLength; - SDL_Rect extents; -}; - -class Menu: public Element -{ - public: -// 1CFF -> 0 001 11 00 111 1 1111 -// 421F -> 0 100 00 10 000 1 1111 - Menu(uint32 x = 0, uint32 y = 0, uint32 w = 0, uint32 h = FONT_HEIGHT, -/* uint16 fgc = 0x1CFF, uint16 bgc = 0x000F, uint16 fgch = 0x421F, - uint16 bgch = 0x1CFF): Element(x, y, w, h), activated(false), clicked(false),*/ -/* uint32 fgc = 0xFF3F3F00, uint32 bgc = 0x7F000000, uint32 fgch = 0xFF878700, - uint32 bgch = 0xFF3F3F00): Element(x, y, w, h), activated(false), clicked(false),*/ -/* uint32 fgc = 0xFFFF3F3F, uint32 bgc = 0xFF7F0000, uint32 fgch = 0xFFFF8787, - uint32 bgch = 0xFFFF3F3F): Element(x, y, w, h), activated(false), clicked(false),*/ - uint32 fgc = 0xFF7F0000, uint32 bgc = 0xFFFF3F3F, uint32 fgch = 0xFFFF3F3F, - uint32 bgch = 0xFFFF8787): Element(x, y, w, h), activated(false), clicked(false), - inside(0), insidePopup(0), fgColor(fgc), bgColor(bgc), fgColorHL(fgch), - bgColorHL(bgch), menuChosen(-1), menuItemChosen(-1) {} - 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 *) {} - void Add(MenuItems mi); - - protected: - bool activated, clicked; - uint32 inside, insidePopup; -// uint16 fgColor, bgColor, fgColorHL, bgColorHL; - uint32 fgColor, bgColor, fgColorHL, bgColorHL; - int menuChosen, menuItemChosen; - - private: - vector itemList; -}; - -void Menu::HandleKey(SDLKey key) -{ - for(uint32 i=0; i= xpos && x < xpos + width) - { - inside = i + 1; - menuChosen = i; - break; - } - - xpos += width; - } - } - - if (!Inside(x, y) && !clicked) - { - menuChosen = -1; - } - - if (itemList[menuChosen].Inside(x, y) && clicked) - { - insidePopup = ((y - itemList[menuChosen].extents.y) / FONT_HEIGHT) + 1; - menuItemChosen = insidePopup - 1; - } -} - -void Menu::HandleMouseButton(uint32 x, uint32 y, bool mouseDown) -{ - if (!clicked) - { - if (mouseDown) - { - if (inside) - clicked = true; - else - menuChosen = -1; // clicked is already false...! - } - } - else // clicked == true - { - if (insidePopup && !mouseDown) // I.e., mouse-button-up - { - activated = true; - if (itemList[menuChosen].item[menuItemChosen].action != NULL) - { -// itemList[menuChosen].item[menuItemChosen].action(); - SDL_Event event; - event.type = SDL_USEREVENT; - event.user.code = MENU_ITEM_CHOSEN; - event.user.data1 = (void *)itemList[menuChosen].item[menuItemChosen].action; - SDL_PushEvent(&event); - - clicked = false, menuChosen = menuItemChosen = -1; - -/* SDL_Event event; - while (SDL_PollEvent(&event)); // Flush the event queue... - event.type = SDL_MOUSEMOTION; - int mx, my; - SDL_GetMouseState(&mx, &my); - event.motion.x = mx, event.motion.y = my; - SDL_PushEvent(&event); // & update mouse position...! -*/ } - } - - if (!inside && !insidePopup && mouseDown) - clicked = false, menuChosen = menuItemChosen = -1; - } -} - -void Menu::Draw(uint32 offsetX/*= 0*/, uint32 offsetY/*= 0*/) -{ - uint32 xpos = extents.x + offsetX; - - for(uint32 i=0; i 0) - DrawStringOpaque(screenBuffer, itemList[menuChosen].extents.x, ypos, - color1, color2, " %-*.*s ", itemList[menuChosen].charLength, - itemList[menuChosen].charLength, itemList[menuChosen].item[i].name.c_str()); - else - DrawStringOpaque(screenBuffer, itemList[menuChosen].extents.x, ypos, - fgColor, bgColor, "%.*s", itemList[menuChosen].charLength + 2, separator); - - ypos += FONT_HEIGHT; - } - } -} - -void Menu::Add(MenuItems mi) -{ - for(uint32 i=0; i mi.charLength) - mi.charLength = mi.item[i].name.length(); - - // Set extents here as well... - mi.extents.x = extents.x + extents.w, mi.extents.y = extents.y + FONT_HEIGHT + 1; - mi.extents.w = (mi.charLength + 2) * FONT_WIDTH, mi.extents.h = mi.item.size() * FONT_HEIGHT; - - itemList.push_back(mi); - extents.w += (mi.title.length() + 2) * FONT_WIDTH; -} - - -//Do we even *need* this? -//Doesn't seem like it... -/*class RootWindow: public Window -{ - public: - RootWindow(Menu * m, Window * w = NULL): menu(m), window(w) {} -//Do we even need to care about this crap? -// { extents.x = extents.y = 0, extents.w = 320, extents.h = 240; } - 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 *) {} - - private: - Menu * menu; - Window * window; - int16 * rootImage[1280 * 240 * 2]; -};//*/ - - -// -// Draw text at the given x/y coordinates. Can invert text as well. -// -void DrawString(uint32 * screen, uint32 x, uint32 y, bool invert, const char * text, ...) -{ - char string[4096]; - va_list arg; - - va_start(arg, text); - vsprintf(string, text, arg); - va_end(arg); - - uint32 pitch = sdlemuGetOverlayWidthInPixels();//GetSDLScreenWidthInPixels(); - uint32 length = strlen(string), address = x + (y * pitch); - - uint32 color1 = 0x0080FF; - uint8 nBlue = (color1 >> 16) & 0xFF, nGreen = (color1 >> 8) & 0xFF, nRed = color1 & 0xFF; - uint8 xorMask = (invert ? 0xFF : 0x00); - - for(uint32 i=0; i> 16) & 0xFF, - eGreen = (existingColor >> 8) & 0xFF, - eRed = existingColor & 0xFF; - - uint8 trans = font2[fontAddr] ^ xorMask; - uint8 invTrans = trans ^ 0xFF; - - uint32 bRed = (eRed * invTrans + nRed * trans) / 255, - bGreen = (eGreen * invTrans + nGreen * trans) / 255, - bBlue = (eBlue * invTrans + nBlue * trans) / 255; - - *(screen + address + xx + (yy * pitch)) = 0xFF000000 | (bBlue << 16) | (bGreen << 8) | bRed; - fontAddr++; - } - } - - address += FONT_WIDTH; - } -} - -// -// Draw text at the given x/y coordinates, using FG/BG colors. -// -void DrawStringOpaque(uint32 * screen, uint32 x, uint32 y, uint32 color1, uint32 color2, const char * text, ...) -{ - char string[4096]; - va_list arg; - - va_start(arg, text); - vsprintf(string, text, arg); - va_end(arg); - - uint32 pitch = sdlemuGetOverlayWidthInPixels(); - uint32 length = strlen(string), address = x + (y * pitch); - - uint8 eBlue = (color2 >> 16) & 0xFF, eGreen = (color2 >> 8) & 0xFF, eRed = color2 & 0xFF, - nBlue = (color1 >> 16) & 0xFF, nGreen = (color1 >> 8) & 0xFF, nRed = color1 & 0xFF; - - for(uint32 i=0; i> 16) & 0xFF, - eGreen = (existingColor >> 8) & 0xFF, - eRed = existingColor & 0xFF, -//This could be done ahead of time, instead of on each pixel... - nBlue = (color >> 16) & 0xFF, - nGreen = (color >> 8) & 0xFF, - nRed = color & 0xFF; - -//This could be sped up by using a table of 5 + 5 + 5 bits (32 levels transparency -> 32768 entries) -//Here we've modified it to have 33 levels of transparency (could have any # we want!) -//because dividing by 32 is faster than dividing by 31...! - uint8 invTrans = 32 - trans; - - uint32 bRed = (eRed * trans + nRed * invTrans) / 32; - uint32 bGreen = (eGreen * trans + nGreen * invTrans) / 32; - uint32 bBlue = (eBlue * trans + nBlue * invTrans) / 32; - - *(screen + address + xx + (yy * pitch)) = 0xFF000000 | (bBlue << 16) | (bGreen << 8) | bRed; - } - - fontAddr++; - } - } - - address += 8; - } -} - -// -// Draw text at the given x/y coordinates, using FG color and overlay alpha blending. -// -void DrawString2(uint32 * screen, uint32 x, uint32 y, uint32 color, uint8 transparency, const char * text, ...) -{ - char string[4096]; - va_list arg; - - va_start(arg, text); - vsprintf(string, text, arg); - va_end(arg); - - uint32 pitch = sdlemuGetOverlayWidthInPixels(); - uint32 length = strlen(string), address = x + (y * pitch); - - color &= 0x00FFFFFF; // Just in case alpha was passed in... - - for(uint32 i=0; i> 8) & 0xFF, - eBlue = (existingColor >> 16) & 0xFF, - - nRed = color & 0xFF, - nGreen = (color >> 8) & 0xFF, - nBlue = (color >> 16) & 0xFF; - - uint8 invTrans = 255 - trans; - uint32 bRed = (eRed * trans + nRed * invTrans) / 255; - uint32 bGreen = (eGreen * trans + nGreen * invTrans) / 255; - uint32 bBlue = (eBlue * trans + nBlue * invTrans) / 255; - - uint32 blendedColor = 0xFF000000 | bRed | (bGreen << 8) | (bBlue << 16); - - *(screen + address + xx + (yy * pitch)) = blendedColor; - - alpha++; - } - - bitmap++; - } - } -}*/ -void DrawTransparentBitmapDeprecated(uint32 * screen, uint32 x, uint32 y, uint32 * bitmap) -{ - uint32 width = bitmap[0], height = bitmap[1]; - bitmap += 2; - - uint32 pitch = sdlemuGetOverlayWidthInPixels();//GetSDLScreenWidthInPixels(); - uint32 address = x + (y * pitch); - - for(uint32 yy=0; yy> 24 != 0x00) // Pixel needs blending - { - uint8 trans = color >> 24; - uint8 invTrans = trans ^ 0xFF;//255 - trans; - - uint8 eRed = existingColor & 0xFF, - eGreen = (existingColor >> 8) & 0xFF, - eBlue = (existingColor >> 16) & 0xFF, - - nRed = color & 0xFF, - nGreen = (color >> 8) & 0xFF, - nBlue = (color >> 16) & 0xFF; - - uint32 bRed = (eRed * invTrans + nRed * trans) / 255; - uint32 bGreen = (eGreen * invTrans + nGreen * trans) / 255; - uint32 bBlue = (eBlue * invTrans + nBlue * trans) / 255; - - blendedColor = 0xFF000000 | bRed | (bGreen << 8) | (bBlue << 16); - } - - *(screen + address + xx + (yy * pitch)) = blendedColor; - bitmap++; - } - } -} - -void DrawTransparentBitmap(uint32 * screen, uint32 x, uint32 y, const void * bitmap) -{ - uint32 pitch = sdlemuGetOverlayWidthInPixels(); - uint32 address = x + (y * pitch); - uint32 count = 0; - - for(uint32 yy=0; yy<((Bitmap *)bitmap)->height; yy++) - { - for(uint32 xx=0; xx<((Bitmap *)bitmap)->width; xx++) - { - uint32 color = ((uint32 *)((Bitmap *)bitmap)->pixelData)[count]; - uint32 blendedColor = color; - uint32 existingColor = *(screen + address + xx + (yy * pitch)); - - if (existingColor >> 24 != 0x00) // Pixel needs blending - { - uint8 trans = color >> 24; - uint8 invTrans = trans ^ 0xFF; - - uint8 eRed = existingColor & 0xFF, - eGreen = (existingColor >> 8) & 0xFF, - eBlue = (existingColor >> 16) & 0xFF, - - nRed = color & 0xFF, - nGreen = (color >> 8) & 0xFF, - nBlue = (color >> 16) & 0xFF; - - uint32 bRed = (eRed * invTrans + nRed * trans) / 255; - uint32 bGreen = (eGreen * invTrans + nGreen * trans) / 255; - uint32 bBlue = (eBlue * invTrans + nBlue * trans) / 255; - -// Instead of $FF, should use the alpha from the destination pixel as the final alpha value... - blendedColor = 0xFF000000 | bRed | (bGreen << 8) | (bBlue << 16); - } - - *(screen + address + xx + (yy * pitch)) = blendedColor; - count++; - } - } -} - -// -// Draw a bitmap without using blending -// -void DrawBitmap(uint32 * screen, uint32 x, uint32 y, const void * bitmap) -{ - uint32 pitch = sdlemuGetOverlayWidthInPixels(); - uint32 address = x + (y * pitch); - uint32 count = 0; - - for(uint32 yy=0; yy<((Bitmap *)bitmap)->height; yy++) - { - for(uint32 xx=0; xx<((Bitmap *)bitmap)->width; xx++) - { - *(screen + address + xx + (yy * pitch)) = ((uint32 *)((Bitmap *)bitmap)->pixelData)[count]; - count++; - } - } -} - -// -// Fill a portion of the screen with the passed in color -// -void FillScreenRectangle(uint32 * screen, uint32 x, uint32 y, uint32 w, uint32 h, uint32 color) -//void ClearScreenRectangle(uint32 * screen, uint32 x, uint32 y, uint32 w, uint32 h) -{ - uint32 pitch = sdlemuGetOverlayWidthInPixels(); - uint32 address = x + (y * pitch); - - for(uint32 yy=0; yyAddElement(new Text(16, 8+15*FONT_HEIGHT, "Curt Vendel for various Jaguar goodies")); window->AddElement(new Text(16, 8+16*FONT_HEIGHT, "The guys over at Atari Age ;-)")); // window->AddElement(new Image(8, 8, &vj_title_small)); - window->AddElement(new Image(width - (vj_title_small.width + 8), 8, &vj_title_small)); +// window->AddElement(new Image(width - (vj_title_small.width + 8), 8, &vj_title_small)); + window->AddElement(new Image(width - (((Bitmap *)vj_title_small)->width + 8), 8, &vj_title_small)); return window; }