mirror of
https://github.com/DragonMinded/jubeatmenu.git
synced 2024-11-14 10:17:36 +01:00
Add sliding animation when changing pages.
This commit is contained in:
parent
e8d967723d
commit
42c8ae4b00
66
JubeatMenu/Animation.cpp
Normal file
66
JubeatMenu/Animation.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include "Animation.h"
|
||||||
|
|
||||||
|
Animation::Animation()
|
||||||
|
{
|
||||||
|
distance = 0;
|
||||||
|
speed = 0.0;
|
||||||
|
lastMilliseconds = 0;
|
||||||
|
location = 0.0;
|
||||||
|
offset = 0;
|
||||||
|
isAnimating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Animation::~Animation()
|
||||||
|
{
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::Animate(int animationOffset, int animationDistance, double pixelsPerSecond)
|
||||||
|
{
|
||||||
|
if (isAnimating) { return; }
|
||||||
|
|
||||||
|
distance = animationDistance;
|
||||||
|
location = 0.0;
|
||||||
|
offset = animationOffset;
|
||||||
|
speed = pixelsPerSecond / (1000.0);
|
||||||
|
isAnimating = true;
|
||||||
|
lastMilliseconds = CurrentMilliseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Animation::IsAnimating()
|
||||||
|
{
|
||||||
|
return isAnimating;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Animation::Position()
|
||||||
|
{
|
||||||
|
int position = (unsigned int)location;
|
||||||
|
if (distance < 0) { position = -position; }
|
||||||
|
return position + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG Animation::CurrentMilliseconds()
|
||||||
|
{
|
||||||
|
SYSTEMTIME time;
|
||||||
|
GetSystemTime(&time);
|
||||||
|
return (time.wSecond * 1000) + time.wMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::Tick()
|
||||||
|
{
|
||||||
|
LONG currentMilliseconds = CurrentMilliseconds();
|
||||||
|
if (currentMilliseconds - lastMilliseconds > 0)
|
||||||
|
{
|
||||||
|
// Calculate how much we should have moved
|
||||||
|
location += speed * (double)(currentMilliseconds - lastMilliseconds);
|
||||||
|
if (location >= abs(distance))
|
||||||
|
{
|
||||||
|
location = abs(distance);
|
||||||
|
isAnimating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remeber we moved
|
||||||
|
lastMilliseconds = currentMilliseconds;
|
||||||
|
}
|
||||||
|
}
|
22
JubeatMenu/Animation.h
Normal file
22
JubeatMenu/Animation.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Animation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Animation();
|
||||||
|
~Animation();
|
||||||
|
|
||||||
|
void Animate(int animationOffset, int animationDistance, double pixelsPerSecond);
|
||||||
|
bool IsAnimating();
|
||||||
|
void Tick();
|
||||||
|
int Position();
|
||||||
|
private:
|
||||||
|
LONG CurrentMilliseconds();
|
||||||
|
|
||||||
|
bool isAnimating;
|
||||||
|
int distance;
|
||||||
|
double location;
|
||||||
|
int offset;
|
||||||
|
double speed;
|
||||||
|
LONG lastMilliseconds;
|
||||||
|
};
|
@ -2,6 +2,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
#include "Animation.h"
|
||||||
|
|
||||||
static Menu *globalMenu;
|
static Menu *globalMenu;
|
||||||
static bool globalQuit;
|
static bool globalQuit;
|
||||||
@ -9,280 +10,315 @@ static unsigned int globalButtonsHeld;
|
|||||||
static unsigned int globalSelected;
|
static unsigned int globalSelected;
|
||||||
static unsigned int globalPage;
|
static unsigned int globalPage;
|
||||||
static unsigned int globalSeconds;
|
static unsigned int globalSeconds;
|
||||||
|
static Animation *globalAnimation;
|
||||||
|
|
||||||
static const unsigned int SELECTION_MAPPING[12] = {
|
static const unsigned int SELECTION_MAPPING[12] = {
|
||||||
0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11
|
0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned int DRAW_MAPPING[15] = {
|
||||||
|
0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned int HIGHLIGHT_MAPPING[15] = {
|
||||||
|
0, 1, 2, 3, 16, 4, 5, 6, 7, 16, 8, 9, 10, 11, 16
|
||||||
};
|
};
|
||||||
|
|
||||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
DestroyWindow(hwnd);
|
DestroyWindow(hwnd);
|
||||||
globalQuit = true;
|
globalQuit = true;
|
||||||
return 0;
|
return 0;
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
globalQuit = true;
|
globalQuit = true;
|
||||||
return 0;
|
return 0;
|
||||||
case WM_QUIT:
|
case WM_QUIT:
|
||||||
globalQuit = true;
|
globalQuit = true;
|
||||||
return 0;
|
return 0;
|
||||||
case WM_PAINT:
|
case WM_ERASEBKGND:
|
||||||
/* Grab the maximum number of menu items */
|
return 1;
|
||||||
unsigned int maxEntries = globalMenu->NumberOfEntries();
|
case WM_PAINT:
|
||||||
|
/* Grab the maximum number of menu items */
|
||||||
|
unsigned int maxEntries = globalMenu->NumberOfEntries();
|
||||||
|
|
||||||
/* Start patinting */
|
/* Set up double buffer */
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
HDC hdc = BeginPaint(hwnd, &ps);
|
HDC windowHdc = BeginPaint(hwnd, &ps);
|
||||||
|
HDC hdc = CreateCompatibleDC(windowHdc);
|
||||||
|
HBITMAP Membitmap = CreateCompatibleBitmap(windowHdc, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
SelectObject(hdc, Membitmap);
|
||||||
|
|
||||||
/* Paint the window background */
|
/* Paint the window background */
|
||||||
HBRUSH background = CreateSolidBrush(RGB(0,0,0));
|
HBRUSH background = CreateSolidBrush(RGB(0,0,0));
|
||||||
FillRect(hdc, &ps.rcPaint, background);
|
FillRect(hdc, &ps.rcPaint, background);
|
||||||
DeleteObject(background);
|
DeleteObject(background);
|
||||||
|
|
||||||
/* Set up text display */
|
/* Set up text display */
|
||||||
SetTextColor(hdc, RGB(240, 240, 240));
|
SetTextColor(hdc, RGB(240, 240, 240));
|
||||||
SetBkMode(hdc, TRANSPARENT);
|
SetBkMode(hdc, TRANSPARENT);
|
||||||
HFONT hItemFont = CreateFont(ITEM_FONT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, L"Verdana");
|
HFONT hItemFont = CreateFont(ITEM_FONT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, L"Verdana");
|
||||||
HFONT hInstructionsFont = CreateFont(INSTRUCTIONS_FONT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, L"Verdana");
|
HFONT hInstructionsFont = CreateFont(INSTRUCTIONS_FONT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, L"Verdana");
|
||||||
HFONT hArrowFont = CreateFont(ARROW_FONT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, L"Verdana");
|
HFONT hArrowFont = CreateFont(ARROW_FONT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, L"Verdana");
|
||||||
|
|
||||||
/* Draw top instructions */
|
/* Set up rectangle display */
|
||||||
{
|
HPEN redPen = CreatePen(PS_SOLID, 2, RGB(255,0,0));
|
||||||
RECT rect;
|
HPEN whitePen = CreatePen(PS_SOLID, 2, RGB(255,255,255));
|
||||||
rect.top = VIEWPORT_TOP + TEXT_PADDING;
|
|
||||||
rect.bottom = VIEWPORT_BOTTOM - TEXT_PADDING;
|
|
||||||
rect.left = TEXT_PADDING;
|
|
||||||
rect.right = SCREEN_WIDTH - TEXT_PADDING;
|
|
||||||
|
|
||||||
char instruction_text[1024];
|
/* Draw top instructions */
|
||||||
sprintf_s(
|
{
|
||||||
instruction_text,
|
RECT rect;
|
||||||
1024,
|
rect.top = VIEWPORT_TOP + TEXT_PADDING;
|
||||||
"Select a game by tapping its panel.\n"
|
rect.bottom = VIEWPORT_BOTTOM - TEXT_PADDING;
|
||||||
"Start %s by tapping the Start Game panel.\n"
|
rect.left = TEXT_PADDING;
|
||||||
"The selected game will auto-start in %d seconds.",
|
rect.right = SCREEN_WIDTH - TEXT_PADDING;
|
||||||
globalMenu->GetEntryName(globalSelected),
|
|
||||||
globalSeconds
|
|
||||||
);
|
|
||||||
|
|
||||||
wchar_t* wString = new wchar_t[4096];
|
char instruction_text[1024];
|
||||||
MultiByteToWideChar(CP_ACP, 0, instruction_text, -1, wString, 4096);
|
sprintf_s(
|
||||||
SelectObject(hdc, hInstructionsFont);
|
instruction_text,
|
||||||
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_LEFT | DT_TOP | DT_WORDBREAK);
|
1024,
|
||||||
delete wString;
|
"Select a game by tapping its panel.\n"
|
||||||
}
|
"Start %s by tapping the Start Game panel.\n"
|
||||||
|
"The selected game will auto-start in %d seconds.",
|
||||||
|
globalMenu->GetEntryName(globalSelected),
|
||||||
|
globalSeconds
|
||||||
|
);
|
||||||
|
|
||||||
/* Draw hover icons for every square, regardless of whether we put graphics in them */
|
wchar_t* wString = new wchar_t[4096];
|
||||||
for( unsigned int position = 0; position < 15; position++ )
|
MultiByteToWideChar(CP_ACP, 0, instruction_text, -1, wString, 4096);
|
||||||
{
|
SelectObject(hdc, hInstructionsFont);
|
||||||
unsigned int xPos = position % 4;
|
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_LEFT | DT_TOP | DT_WORDBREAK);
|
||||||
unsigned int yPos = position / 4;
|
delete wString;
|
||||||
|
}
|
||||||
|
|
||||||
/* There is an extra pixel of bump for the second half of the squares */
|
/* Draw hover icons for every square, regardless of whether we put graphics in them */
|
||||||
unsigned int xBump = xPos >= 2 ? 1 : 0;
|
{
|
||||||
unsigned int yBump = yPos >= 2 ? 1 : 0;
|
/* Set up background colors */
|
||||||
|
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
||||||
|
SetDCBrushColor(hdc, RGB(0,0,0));
|
||||||
|
|
||||||
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * yPos) + yBump;
|
/* Set up border color to show current held buttons */
|
||||||
unsigned int bottom = top + BUTTON_WIDTH;
|
SelectObject(hdc, redPen);
|
||||||
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * xPos) + xBump;
|
|
||||||
unsigned int right = left + BUTTON_HEIGHT;
|
|
||||||
|
|
||||||
/* Set up background colors */
|
|
||||||
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
|
||||||
SetDCBrushColor(hdc, RGB(0,0,0));
|
|
||||||
|
|
||||||
// Set up border color to show current held buttons
|
/* Intentionally skip button 16 because pressing it will always
|
||||||
SelectObject(hdc, GetStockObject(DC_PEN));
|
insta-launch the selected game, so we will never need to show
|
||||||
if ((globalButtonsHeld >> position) & 1)
|
a hover square. */
|
||||||
{
|
for( unsigned int position = 0; position < 15; position++ )
|
||||||
SetDCPenColor(hdc, RGB(255,0,0));
|
{
|
||||||
}
|
if (!((globalButtonsHeld >> position) & 1))
|
||||||
else
|
{
|
||||||
{
|
// This button isn't being held, no need to show a held box.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (globalAnimation->IsAnimating() && position < 12)
|
||||||
// Draw bounding rectangle
|
{
|
||||||
Rectangle(hdc, left, top, right, bottom);
|
// Don't show hover while moving selection panels.
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw selection button */
|
unsigned int xPos = position % 4;
|
||||||
{
|
unsigned int yPos = position / 4;
|
||||||
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * 3) + 1;
|
|
||||||
unsigned int bottom = top + BUTTON_WIDTH;
|
|
||||||
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * 3) + 1;
|
|
||||||
unsigned int right = left + BUTTON_HEIGHT;
|
|
||||||
|
|
||||||
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
/* There is an extra pixel of bump for the second half of the squares */
|
||||||
SetDCBrushColor(hdc, RGB(24,24,24));
|
unsigned int xBump = xPos >= 2 ? 1 : 0;
|
||||||
SetDCPenColor(hdc, RGB(255,255,255));
|
unsigned int yBump = yPos >= 2 ? 1 : 0;
|
||||||
Rectangle(hdc, left, top, right, bottom);
|
|
||||||
|
|
||||||
RECT rect;
|
|
||||||
rect.top = top + TEXT_PADDING;
|
|
||||||
rect.bottom = bottom - TEXT_PADDING;
|
|
||||||
rect.left = left + TEXT_PADDING;
|
|
||||||
rect.right = right - TEXT_PADDING;
|
|
||||||
|
|
||||||
char start_text[64];
|
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * yPos) + yBump;
|
||||||
sprintf_s(start_text, 64, "Start Game\n\n%d seconds left", globalSeconds);
|
unsigned int bottom = top + BUTTON_WIDTH;
|
||||||
|
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * xPos) + xBump;
|
||||||
|
unsigned int right = left + BUTTON_HEIGHT;
|
||||||
|
|
||||||
wchar_t* wString = new wchar_t[4096];
|
// Draw bounding rectangle
|
||||||
MultiByteToWideChar(CP_ACP, 0, start_text, -1, wString, 4096);
|
Rectangle(hdc, left, top, right, bottom);
|
||||||
SelectObject(hdc, hItemFont);
|
}
|
||||||
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_CENTER | DT_TOP);
|
}
|
||||||
delete wString;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Draw previous/next page buttons */
|
/* Draw selection button */
|
||||||
if (maxEntries > GAMES_PER_PAGE)
|
{
|
||||||
{
|
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * 3) + 1;
|
||||||
unsigned int max_pages = ((maxEntries - GAMES_PER_PAGE) + 2) / 3;
|
unsigned int bottom = top + BUTTON_WIDTH;
|
||||||
|
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * 3) + 1;
|
||||||
/* Scroll left button */
|
unsigned int right = left + BUTTON_HEIGHT;
|
||||||
if (globalPage < max_pages)
|
|
||||||
{
|
|
||||||
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * 3) + 1;
|
|
||||||
unsigned int bottom = top + BUTTON_WIDTH;
|
|
||||||
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * 0) + 1;
|
|
||||||
unsigned int right = left + BUTTON_HEIGHT;
|
|
||||||
|
|
||||||
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
||||||
SetDCBrushColor(hdc, RGB(24,24,24));
|
SetDCBrushColor(hdc, RGB(24,24,24));
|
||||||
if ((globalButtonsHeld >> 12) & 1)
|
SelectObject(hdc, whitePen);
|
||||||
{
|
Rectangle(hdc, left, top, right, bottom);
|
||||||
SetDCPenColor(hdc, RGB(255,0,0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetDCPenColor(hdc, RGB(255,255,255));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw bounding rectangle
|
RECT rect;
|
||||||
Rectangle(hdc, left, top, right, bottom);
|
rect.top = top + TEXT_PADDING;
|
||||||
|
rect.bottom = bottom - TEXT_PADDING;
|
||||||
// Draw text
|
rect.left = left + TEXT_PADDING;
|
||||||
RECT rect;
|
rect.right = right - TEXT_PADDING;
|
||||||
rect.top = top + TEXT_PADDING;
|
|
||||||
rect.bottom = bottom - TEXT_PADDING;
|
|
||||||
rect.left = left + TEXT_PADDING;
|
|
||||||
rect.right = right - TEXT_PADDING;
|
|
||||||
|
|
||||||
wchar_t* wString = new wchar_t[4096];
|
char start_text[64];
|
||||||
MultiByteToWideChar(CP_ACP, 0, "<<", -1, wString, 4096);
|
sprintf_s(start_text, 64, "Start Game\n\n%d seconds left", globalSeconds);
|
||||||
SelectObject(hdc, hArrowFont);
|
|
||||||
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
|
||||||
delete wString;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scroll right button */
|
wchar_t* wString = new wchar_t[4096];
|
||||||
if (globalPage > 0)
|
MultiByteToWideChar(CP_ACP, 0, start_text, -1, wString, 4096);
|
||||||
{
|
SelectObject(hdc, hItemFont);
|
||||||
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * 3) + 1;
|
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_CENTER | DT_TOP);
|
||||||
unsigned int bottom = top + BUTTON_WIDTH;
|
delete wString;
|
||||||
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * 1) + 1;
|
}
|
||||||
unsigned int right = left + BUTTON_HEIGHT;
|
|
||||||
|
|
||||||
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
/* Draw previous/next page buttons */
|
||||||
SetDCBrushColor(hdc, RGB(24,24,24));
|
if (maxEntries > GAMES_PER_PAGE)
|
||||||
if ((globalButtonsHeld >> 13) & 1)
|
{
|
||||||
{
|
unsigned int max_pages = ((maxEntries - GAMES_PER_PAGE) + 2) / 3;
|
||||||
SetDCPenColor(hdc, RGB(255,0,0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetDCPenColor(hdc, RGB(255,255,255));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw bounding rectangle
|
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
||||||
Rectangle(hdc, left, top, right, bottom);
|
SetDCBrushColor(hdc, RGB(24,24,24));
|
||||||
|
|
||||||
// Draw text
|
|
||||||
RECT rect;
|
|
||||||
rect.top = top + TEXT_PADDING;
|
|
||||||
rect.bottom = bottom - TEXT_PADDING;
|
|
||||||
rect.left = left + TEXT_PADDING;
|
|
||||||
rect.right = right - TEXT_PADDING;
|
|
||||||
|
|
||||||
wchar_t* wString = new wchar_t[4096];
|
/* Scroll left button */
|
||||||
MultiByteToWideChar(CP_ACP, 0, ">>", -1, wString, 4096);
|
if (globalPage < max_pages)
|
||||||
SelectObject(hdc, hArrowFont);
|
{
|
||||||
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * 3) + 1;
|
||||||
delete wString;
|
unsigned int bottom = top + BUTTON_WIDTH;
|
||||||
}
|
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * 0) + 1;
|
||||||
}
|
unsigned int right = left + BUTTON_HEIGHT;
|
||||||
|
|
||||||
/* Draw each menu item */
|
|
||||||
for( unsigned int position = 0; position < 12; position++ ) {
|
|
||||||
unsigned int xPos = position % 4;
|
|
||||||
unsigned int yPos = position / 4;
|
|
||||||
|
|
||||||
/* Look up the actual item at this position */
|
if ((globalButtonsHeld >> 12) & 1)
|
||||||
unsigned int item = SELECTION_MAPPING[position] + (globalPage * 3);
|
{
|
||||||
if (item >= maxEntries) { continue; }
|
SelectObject(hdc, redPen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelectObject(hdc, whitePen);
|
||||||
|
}
|
||||||
|
|
||||||
/* There is an extra pixel of bump for the second half of the squares */
|
// Draw bounding rectangle
|
||||||
unsigned int xBump = xPos >= 2 ? 1 : 0;
|
Rectangle(hdc, left, top, right, bottom);
|
||||||
unsigned int yBump = yPos >= 2 ? 1 : 0;
|
|
||||||
|
|
||||||
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * yPos) + yBump;
|
// Draw text
|
||||||
unsigned int bottom = top + BUTTON_WIDTH;
|
RECT rect;
|
||||||
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * xPos) + xBump;
|
rect.top = top + TEXT_PADDING;
|
||||||
unsigned int right = left + BUTTON_HEIGHT;
|
rect.bottom = bottom - TEXT_PADDING;
|
||||||
|
rect.left = left + TEXT_PADDING;
|
||||||
/* Set up background colors */
|
rect.right = right - TEXT_PADDING;
|
||||||
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
|
||||||
if (globalSelected == item)
|
|
||||||
{
|
|
||||||
SetDCBrushColor(hdc, RGB(96,96,96));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetDCBrushColor(hdc, RGB(24,24,24));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up border color to show current held buttons
|
wchar_t* wString = new wchar_t[4096];
|
||||||
SelectObject(hdc, GetStockObject(DC_PEN));
|
MultiByteToWideChar(CP_ACP, 0, "<<", -1, wString, 4096);
|
||||||
if ((globalButtonsHeld >> position) & 1)
|
SelectObject(hdc, hArrowFont);
|
||||||
{
|
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||||
SetDCPenColor(hdc, RGB(255,0,0));
|
delete wString;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
SetDCPenColor(hdc, RGB(255,255,255));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw bounding rectangle
|
|
||||||
Rectangle(hdc, left, top, right, bottom);
|
|
||||||
|
|
||||||
// Set text color
|
/* Scroll right button */
|
||||||
SelectObject(hdc, GetStockObject(DC_PEN));
|
if (globalPage > 0)
|
||||||
SetDCPenColor(hdc, RGB(255,255,255));
|
{
|
||||||
|
unsigned int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * 3) + 1;
|
||||||
|
unsigned int bottom = top + BUTTON_WIDTH;
|
||||||
|
unsigned int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * 1) + 1;
|
||||||
|
unsigned int right = left + BUTTON_HEIGHT;
|
||||||
|
|
||||||
// Draw text
|
if ((globalButtonsHeld >> 13) & 1)
|
||||||
RECT rect;
|
{
|
||||||
rect.top = top + TEXT_PADDING;
|
SelectObject(hdc, redPen);
|
||||||
rect.bottom = bottom - TEXT_PADDING;
|
}
|
||||||
rect.left = left + TEXT_PADDING;
|
else
|
||||||
rect.right = right - TEXT_PADDING;
|
{
|
||||||
|
SelectObject(hdc, whitePen);
|
||||||
|
}
|
||||||
|
|
||||||
wchar_t* wString = new wchar_t[4096];
|
// Draw bounding rectangle
|
||||||
MultiByteToWideChar(CP_ACP, 0, globalMenu->GetEntryName(item), -1, wString, 4096);
|
Rectangle(hdc, left, top, right, bottom);
|
||||||
SelectObject(hdc, hItemFont);
|
|
||||||
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_CENTER | DT_TOP | DT_WORDBREAK);
|
|
||||||
delete wString;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteObject(hItemFont);
|
// Draw text
|
||||||
DeleteObject(hInstructionsFont);
|
RECT rect;
|
||||||
DeleteObject(hArrowFont);
|
rect.top = top + TEXT_PADDING;
|
||||||
|
rect.bottom = bottom - TEXT_PADDING;
|
||||||
EndPaint(hwnd, &ps);
|
rect.left = left + TEXT_PADDING;
|
||||||
return 0;
|
rect.right = right - TEXT_PADDING;
|
||||||
}
|
|
||||||
|
wchar_t* wString = new wchar_t[4096];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, ">>", -1, wString, 4096);
|
||||||
|
SelectObject(hdc, hArrowFont);
|
||||||
|
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||||
|
delete wString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw each menu item */
|
||||||
|
for( unsigned int position = 0; position < 15; position++ )
|
||||||
|
{
|
||||||
|
/* Leave room for animating left/right swipe */
|
||||||
|
unsigned int xPos = position % 5;
|
||||||
|
unsigned int yPos = position / 5;
|
||||||
|
|
||||||
|
/* Look up the actual item at this position */
|
||||||
|
unsigned int item = DRAW_MAPPING[position] + (globalPage * 3);
|
||||||
|
if (item >= maxEntries) { continue; }
|
||||||
|
|
||||||
|
/* There is an extra pixel of bump for the second half of the squares */
|
||||||
|
unsigned int xBump = xPos >= 2 ? 1 : 0;
|
||||||
|
unsigned int yBump = yPos >= 2 ? 1 : 0;
|
||||||
|
|
||||||
|
/* Adjust position for animations */
|
||||||
|
int animationBump = 0;
|
||||||
|
if (globalAnimation->IsAnimating())
|
||||||
|
{
|
||||||
|
animationBump = globalAnimation->Position();
|
||||||
|
}
|
||||||
|
|
||||||
|
int top = BUTTON_TOP + (BUTTON_VERTICAL_STRIDE * yPos) + yBump;
|
||||||
|
int bottom = top + BUTTON_WIDTH;
|
||||||
|
int left = BUTTON_LEFT + (BUTTON_HORIZONTAL_STRIDE * xPos) + xBump + animationBump;
|
||||||
|
int right = left + BUTTON_HEIGHT;
|
||||||
|
|
||||||
|
/* Set up background colors */
|
||||||
|
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
||||||
|
if (globalSelected == item)
|
||||||
|
{
|
||||||
|
SetDCBrushColor(hdc, RGB(96,96,96));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetDCBrushColor(hdc, RGB(24,24,24));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up border color to show current held buttons
|
||||||
|
if (!globalAnimation->IsAnimating() && ((globalButtonsHeld >> HIGHLIGHT_MAPPING[position]) & 1))
|
||||||
|
{
|
||||||
|
SelectObject(hdc, redPen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelectObject(hdc, whitePen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw bounding rectangle
|
||||||
|
Rectangle(hdc, left, top, right, bottom);
|
||||||
|
|
||||||
|
// Draw text
|
||||||
|
RECT rect;
|
||||||
|
rect.top = top + TEXT_PADDING;
|
||||||
|
rect.bottom = bottom - TEXT_PADDING;
|
||||||
|
rect.left = left + TEXT_PADDING;
|
||||||
|
rect.right = right - TEXT_PADDING;
|
||||||
|
|
||||||
|
wchar_t* wString = new wchar_t[4096];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, globalMenu->GetEntryName(item), -1, wString, 4096);
|
||||||
|
SelectObject(hdc, hItemFont);
|
||||||
|
DrawText(hdc, wString, -1, &rect, DT_HIDEPREFIX | DT_CENTER | DT_TOP | DT_WORDBREAK);
|
||||||
|
delete wString;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteObject(hItemFont);
|
||||||
|
DeleteObject(hInstructionsFont);
|
||||||
|
DeleteObject(hArrowFont);
|
||||||
|
|
||||||
|
/* Copy double-buffer over */
|
||||||
|
BitBlt(windowHdc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, hdc, 0, 0, SRCCOPY);
|
||||||
|
DeleteObject(Membitmap);
|
||||||
|
DeleteDC(hdc);
|
||||||
|
DeleteDC(windowHdc);
|
||||||
|
|
||||||
|
EndPaint(hwnd, &ps);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
@ -290,138 +326,183 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
Display::Display(HINSTANCE hInstance, IO *ioInst, Menu *mInst)
|
Display::Display(HINSTANCE hInstance, IO *ioInst, Menu *mInst)
|
||||||
{
|
{
|
||||||
inst = hInstance;
|
globalAnimation = new Animation();
|
||||||
globalMenu = mInst;
|
inst = hInstance;
|
||||||
io = ioInst;
|
globalMenu = mInst;
|
||||||
menu = mInst;
|
io = ioInst;
|
||||||
page = 0;
|
menu = mInst;
|
||||||
selected = 0;
|
page = 0;
|
||||||
|
selected = 0;
|
||||||
|
newPage = -1;
|
||||||
|
lastLocation = 0;
|
||||||
|
|
||||||
// Register the callback
|
// Register the callback
|
||||||
WNDCLASS wc = { };
|
WNDCLASS wc = { };
|
||||||
wc.lpfnWndProc = WindowProc;
|
wc.lpfnWndProc = WindowProc;
|
||||||
wc.hInstance = inst;
|
wc.hInstance = inst;
|
||||||
wc.lpszClassName = CLASS_NAME;
|
wc.lpszClassName = CLASS_NAME;
|
||||||
RegisterClass(&wc);
|
RegisterClass(&wc);
|
||||||
globalQuit = false;
|
globalQuit = false;
|
||||||
globalButtonsHeld = 0;
|
globalButtonsHeld = 0;
|
||||||
globalSelected = selected;
|
globalSelected = selected;
|
||||||
globalPage = page;
|
globalPage = page;
|
||||||
globalSeconds = menu->SecondsLeft();
|
globalSeconds = menu->SecondsLeft();
|
||||||
|
|
||||||
// Create an empty window
|
// Create an empty window
|
||||||
hwnd = CreateWindow(CLASS_NAME, 0, WS_BORDER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, inst, NULL);
|
hwnd = CreateWindow(CLASS_NAME, 0, WS_BORDER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, inst, NULL);
|
||||||
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
|
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
|
||||||
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
|
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
|
||||||
SetWindowLong(hwnd, GWL_STYLE, lStyle);
|
SetWindowLong(hwnd, GWL_STYLE, lStyle);
|
||||||
LONG lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
LONG lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||||
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
|
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
|
||||||
SetWindowLong(hwnd, GWL_EXSTYLE, lExStyle);
|
SetWindowLong(hwnd, GWL_EXSTYLE, lExStyle);
|
||||||
|
|
||||||
/* Display it */
|
/* Display it */
|
||||||
SetWindowPos(hwnd, NULL, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
SetWindowPos(hwnd, NULL, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||||
ShowWindow(hwnd, SW_SHOW);
|
ShowWindow(hwnd, SW_SHOW);
|
||||||
UpdateWindow(hwnd);
|
UpdateWindow(hwnd);
|
||||||
ShowCursor(false);
|
ShowCursor(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Display::~Display(void)
|
Display::~Display()
|
||||||
{
|
{
|
||||||
ShowCursor(true);
|
ShowCursor(true);
|
||||||
DestroyWindow(hwnd);
|
DestroyWindow(hwnd);
|
||||||
UnregisterClass(CLASS_NAME, inst);
|
UnregisterClass(CLASS_NAME, inst);
|
||||||
|
delete globalAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::Tick(void)
|
void Display::Tick(void)
|
||||||
{
|
{
|
||||||
/* Handle windows message pump */
|
/* Handle windows message pump */
|
||||||
MSG msg = { };
|
MSG msg = { };
|
||||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||||
{
|
{
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grab the currently held buttons, calculate newly pressed */
|
/* Don't handle input while animating */
|
||||||
bool moved = false;
|
unsigned int buttonsHeld = io->ButtonsHeld();
|
||||||
unsigned int buttonsHeld = io->ButtonsHeld();
|
globalAnimation->Tick();
|
||||||
|
if (globalAnimation->IsAnimating())
|
||||||
|
{
|
||||||
|
bool update = false;
|
||||||
|
|
||||||
/* Figure out actions */
|
if (globalButtonsHeld != buttonsHeld)
|
||||||
if (menu->NumberOfEntries() > GAMES_PER_PAGE)
|
{
|
||||||
{
|
globalButtonsHeld = buttonsHeld;
|
||||||
unsigned int max_pages = ((menu->NumberOfEntries() - GAMES_PER_PAGE) + 2) / 3;
|
update = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Activate page left/right buttons */
|
if (lastLocation != globalAnimation->Position())
|
||||||
if (io->ButtonPressed(BUTTON_13))
|
{
|
||||||
{
|
lastLocation = globalAnimation->Position();
|
||||||
/* Scroll left */
|
update = true;
|
||||||
if (page < max_pages)
|
}
|
||||||
{
|
|
||||||
page++;
|
|
||||||
moved = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (io->ButtonPressed(BUTTON_14))
|
if (update)
|
||||||
{
|
{
|
||||||
/* Scroll right */
|
InvalidateRect(hwnd, NULL, FALSE);
|
||||||
if (page > 0)
|
UpdateWindow(hwnd);
|
||||||
{
|
}
|
||||||
page--;
|
return;
|
||||||
moved = true;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moved) {
|
/* See if we need to update the page after finishing animation */
|
||||||
/* Allow button presses to make selections */
|
if (newPage >= 0)
|
||||||
for (unsigned int btn = 0; btn < 12; btn++) {
|
{
|
||||||
if (io->ButtonPressed(1 << btn)) {
|
page = newPage;
|
||||||
unsigned int item = SELECTION_MAPPING[btn] + (globalPage * 3);
|
globalPage = page;
|
||||||
if (item < menu->NumberOfEntries())
|
newPage = -1;
|
||||||
{
|
globalButtonsHeld = buttonsHeld;
|
||||||
selected = item;
|
InvalidateRect(hwnd, NULL, FALSE);
|
||||||
}
|
UpdateWindow(hwnd);
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the screen to show any button presses or selection
|
/* Grab the currently held buttons, calculate newly pressed */
|
||||||
changes. */
|
bool moved = false;
|
||||||
bool update = false;
|
|
||||||
if (globalButtonsHeld != buttonsHeld)
|
|
||||||
{
|
|
||||||
globalButtonsHeld = buttonsHeld;
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
if (globalSelected != selected)
|
|
||||||
{
|
|
||||||
globalSelected = selected;
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
if (globalPage != page)
|
|
||||||
{
|
|
||||||
globalPage = page;
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
if (globalSeconds != menu->SecondsLeft()) {
|
|
||||||
globalSeconds = menu->SecondsLeft();
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update)
|
/* Figure out actions */
|
||||||
{
|
if (menu->NumberOfEntries() > GAMES_PER_PAGE)
|
||||||
InvalidateRect(hwnd, NULL, NULL);
|
{
|
||||||
UpdateWindow(hwnd);
|
unsigned int max_pages = ((menu->NumberOfEntries() - GAMES_PER_PAGE) + 2) / 3;
|
||||||
}
|
|
||||||
|
/* Activate page left/right buttons */
|
||||||
|
if (io->ButtonPressed(BUTTON_13))
|
||||||
|
{
|
||||||
|
/* Scroll left */
|
||||||
|
if (page < max_pages)
|
||||||
|
{
|
||||||
|
globalAnimation->Animate(0, -BUTTON_HORIZONTAL_STRIDE, ANIMATION_SPEED);
|
||||||
|
lastLocation = globalAnimation->Position();
|
||||||
|
newPage = page + 1;
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
} else if (io->ButtonPressed(BUTTON_14))
|
||||||
|
{
|
||||||
|
/* Scroll right */
|
||||||
|
if (page > 0)
|
||||||
|
{
|
||||||
|
globalAnimation->Animate(-BUTTON_HORIZONTAL_STRIDE, BUTTON_HORIZONTAL_STRIDE, ANIMATION_SPEED);
|
||||||
|
lastLocation = globalAnimation->Position();
|
||||||
|
page--;
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!moved)
|
||||||
|
{
|
||||||
|
/* Allow button presses to make selections */
|
||||||
|
for (unsigned int btn = 0; btn < 12; btn++) {
|
||||||
|
if (io->ButtonPressed(1 << btn)) {
|
||||||
|
unsigned int item = SELECTION_MAPPING[btn] + (globalPage * 3);
|
||||||
|
if (item < menu->NumberOfEntries())
|
||||||
|
{
|
||||||
|
selected = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the screen to show any button presses or selection
|
||||||
|
changes. */
|
||||||
|
bool update = false;
|
||||||
|
if (globalButtonsHeld != buttonsHeld)
|
||||||
|
{
|
||||||
|
globalButtonsHeld = buttonsHeld;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
if (globalSelected != selected)
|
||||||
|
{
|
||||||
|
globalSelected = selected;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
if (globalPage != page)
|
||||||
|
{
|
||||||
|
globalPage = page;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
if (globalSeconds != menu->SecondsLeft()) {
|
||||||
|
globalSeconds = menu->SecondsLeft();
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
InvalidateRect(hwnd, NULL, FALSE);
|
||||||
|
UpdateWindow(hwnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Display::WasClosed()
|
bool Display::WasClosed()
|
||||||
{
|
{
|
||||||
return globalQuit;
|
return globalQuit;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Display::GetSelectedItem()
|
unsigned int Display::GetSelectedItem()
|
||||||
{
|
{
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
@ -27,30 +27,34 @@
|
|||||||
|
|
||||||
#define TEXT_PADDING 10
|
#define TEXT_PADDING 10
|
||||||
|
|
||||||
|
#define ANIMATION_SPEED 1000
|
||||||
|
|
||||||
/* Number of games to display on one screen */
|
/* Number of games to display on one screen */
|
||||||
#define GAMES_PER_PAGE 12
|
#define GAMES_PER_PAGE 12
|
||||||
|
|
||||||
class Display
|
class Display
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Display(HINSTANCE hInstance, IO *ioInst, Menu *mInst);
|
Display(HINSTANCE hInstance, IO *ioInst, Menu *mInst);
|
||||||
~Display(void);
|
~Display();
|
||||||
|
|
||||||
void Tick();
|
void Tick();
|
||||||
bool WasClosed();
|
bool WasClosed();
|
||||||
|
|
||||||
void ButtonPress(int button);
|
void ButtonPress(int button);
|
||||||
void ButtonRelease(int button);
|
void ButtonRelease(int button);
|
||||||
|
|
||||||
unsigned int GetSelectedItem();
|
unsigned int GetSelectedItem();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HINSTANCE inst;
|
HINSTANCE inst;
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
|
||||||
Menu *menu;
|
Menu *menu;
|
||||||
IO *io;
|
IO *io;
|
||||||
|
|
||||||
unsigned int page;
|
int newPage;
|
||||||
unsigned int selected;
|
unsigned int page;
|
||||||
|
unsigned int selected;
|
||||||
|
int lastLocation;
|
||||||
};
|
};
|
||||||
|
@ -2,147 +2,147 @@
|
|||||||
|
|
||||||
IO::IO()
|
IO::IO()
|
||||||
{
|
{
|
||||||
/* Start with not being ready */
|
/* Start with not being ready */
|
||||||
is_ready = false;
|
is_ready = false;
|
||||||
|
|
||||||
/* Load the log function so we can output debugging */
|
/* Load the log function so we can output debugging */
|
||||||
log_function = NULL;
|
log_function = NULL;
|
||||||
core = GetModuleHandleA("avs2-core.dll");
|
core = GetModuleHandleA("avs2-core.dll");
|
||||||
if (core != NULL) {
|
if (core != NULL) {
|
||||||
log_function = (log_func)GetProcAddress(core, "XCgsqzn000017c");
|
log_function = (log_func)GetProcAddress(core, "XCgsqzn000017c");
|
||||||
} else {
|
} else {
|
||||||
core = GetModuleHandleA("libavs-win32.dll");
|
core = GetModuleHandleA("libavs-win32.dll");
|
||||||
if (core != NULL) {
|
if (core != NULL) {
|
||||||
log_function = (log_func)GetProcAddress(core, "XCd229cc000018");
|
log_function = (log_func)GetProcAddress(core, "XCd229cc000018");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Initializing device.dll");
|
debug("Initializing device.dll");
|
||||||
|
|
||||||
device = GetModuleHandleA("device.dll");
|
device = GetModuleHandleA("device.dll");
|
||||||
|
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
debug("Missing device.dll. Did you run this from the right directory?");
|
debug("Missing device.dll. Did you run this from the right directory?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_initialize = (INT_RET_ONE_ARG) GetProcAddress(device, "device_initialize");
|
device_initialize = (INT_RET_ONE_ARG) GetProcAddress(device, "device_initialize");
|
||||||
device_is_initialized = (INT_RET_NO_ARGS) GetProcAddress(device, "device_is_initialized");
|
device_is_initialized = (INT_RET_NO_ARGS) GetProcAddress(device, "device_is_initialized");
|
||||||
device_get_status = (INT_RET_NO_ARGS) GetProcAddress(device, "device_get_status");
|
device_get_status = (INT_RET_NO_ARGS) GetProcAddress(device, "device_get_status");
|
||||||
device_set_panel_mode = (INT_RET_ONE_ARG) GetProcAddress(device, "device_set_panel_mode");
|
device_set_panel_mode = (INT_RET_ONE_ARG) GetProcAddress(device, "device_set_panel_mode");
|
||||||
device_get_panel_trg_on = (INT_RET_THREE_ARGS) GetProcAddress(device, "device_get_panel_trg_on");
|
device_get_panel_trg_on = (INT_RET_THREE_ARGS) GetProcAddress(device, "device_get_panel_trg_on");
|
||||||
device_get_panel_trg_off = (INT_RET_THREE_ARGS) GetProcAddress(device, "device_get_panel_trg_off");
|
device_get_panel_trg_off = (INT_RET_THREE_ARGS) GetProcAddress(device, "device_get_panel_trg_off");
|
||||||
device_get_panel_trg_short_on = (INT_RET_THREE_ARGS) GetProcAddress(device, "device_get_panel_trg_short_on");
|
device_get_panel_trg_short_on = (INT_RET_THREE_ARGS) GetProcAddress(device, "device_get_panel_trg_short_on");
|
||||||
device_update = (INT_RET_NO_ARGS) GetProcAddress(device, "device_update");
|
device_update = (INT_RET_NO_ARGS) GetProcAddress(device, "device_update");
|
||||||
device_finalize = (INT_RET_NO_ARGS) GetProcAddress(device, "device_finalize");
|
device_finalize = (INT_RET_NO_ARGS) GetProcAddress(device, "device_finalize");
|
||||||
|
|
||||||
if (
|
if (
|
||||||
device_initialize == NULL ||
|
device_initialize == NULL ||
|
||||||
device_is_initialized == NULL ||
|
device_is_initialized == NULL ||
|
||||||
device_get_status == NULL ||
|
device_get_status == NULL ||
|
||||||
device_set_panel_mode == NULL ||
|
device_set_panel_mode == NULL ||
|
||||||
device_update == NULL ||
|
device_update == NULL ||
|
||||||
device_get_panel_trg_on == NULL ||
|
device_get_panel_trg_on == NULL ||
|
||||||
device_get_panel_trg_off == NULL ||
|
device_get_panel_trg_off == NULL ||
|
||||||
device_get_panel_trg_short_on == NULL ||
|
device_get_panel_trg_short_on == NULL ||
|
||||||
device_finalize == NULL
|
device_finalize == NULL
|
||||||
) {
|
) {
|
||||||
debug("Couldn't find correct functions to call! Did you use the right DLLs?");
|
debug("Couldn't find correct functions to call! Did you use the right DLLs?");
|
||||||
FreeLibrary(device);
|
FreeLibrary(device);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, initialize and verify.
|
// First, initialize and verify.
|
||||||
debug("Initializing P4IO device");
|
debug("Initializing P4IO device");
|
||||||
device_initialize(0);
|
device_initialize(0);
|
||||||
|
|
||||||
if (!device_is_initialized()) {
|
|
||||||
debug("Couldn't initialize P4IO device");
|
|
||||||
FreeLibrary(device);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device_get_status() < 0) {
|
|
||||||
debug("P4IO device status returns error!");
|
|
||||||
FreeLibrary(device);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure to read panels
|
if (!device_is_initialized()) {
|
||||||
debug("Configuring P4IO driver");
|
debug("Couldn't initialize P4IO device");
|
||||||
device_set_panel_mode(0);
|
FreeLibrary(device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// We're ready to roll
|
if (device_get_status() < 0) {
|
||||||
debug("P4IO driver ready for input");
|
debug("P4IO device status returns error!");
|
||||||
is_ready = true;
|
FreeLibrary(device);
|
||||||
buttons = 0;
|
return;
|
||||||
lastButtons = 0;
|
}
|
||||||
|
|
||||||
|
// Configure to read panels
|
||||||
|
debug("Configuring P4IO driver");
|
||||||
|
device_set_panel_mode(0);
|
||||||
|
|
||||||
|
// We're ready to roll
|
||||||
|
debug("P4IO driver ready for input");
|
||||||
|
is_ready = true;
|
||||||
|
buttons = 0;
|
||||||
|
lastButtons = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IO::~IO(void)
|
IO::~IO()
|
||||||
{
|
{
|
||||||
if (!is_ready) { return; }
|
if (!is_ready) { return; }
|
||||||
|
|
||||||
debug("Finalizing P4IO driver");
|
debug("Finalizing P4IO driver");
|
||||||
device_finalize();
|
device_finalize();
|
||||||
FreeLibrary(device);
|
FreeLibrary(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IO::Ready()
|
bool IO::Ready()
|
||||||
{
|
{
|
||||||
return is_ready;
|
return is_ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IO::ErrorMessage(char *msg)
|
void IO::ErrorMessage(char *msg)
|
||||||
{
|
{
|
||||||
debug(msg);
|
debug(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IO::Tick()
|
void IO::Tick()
|
||||||
{
|
{
|
||||||
if (!is_ready) { return; }
|
if (!is_ready) { return; }
|
||||||
|
|
||||||
if(device_is_initialized()) {
|
if(device_is_initialized()) {
|
||||||
device_update();
|
device_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember last buttons so we can calculate newly
|
// Remember last buttons so we can calculate newly
|
||||||
// pressed buttons.
|
// pressed buttons.
|
||||||
lastButtons = buttons;
|
lastButtons = buttons;
|
||||||
|
|
||||||
for (int panel = 0; panel < 16; panel++) {
|
for (int panel = 0; panel < 16; panel++) {
|
||||||
int output[2] = { 0 };
|
int output[2] = { 0 };
|
||||||
|
|
||||||
device_get_panel_trg_on(panel % 4, panel / 4, output);
|
device_get_panel_trg_on(panel % 4, panel / 4, output);
|
||||||
if (output[0] != 0) {
|
if (output[0] != 0) {
|
||||||
// Track the button release
|
// Track the button release
|
||||||
buttons &= ~(1 << panel);
|
buttons &= ~(1 << panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
device_get_panel_trg_off(panel % 4, panel / 4, output);
|
device_get_panel_trg_off(panel % 4, panel / 4, output);
|
||||||
if (output[0] != 0) {
|
if (output[0] != 0) {
|
||||||
// Track the button press
|
// Track the button press
|
||||||
buttons |= (1 << panel);
|
buttons |= (1 << panel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int IO::ButtonsHeld()
|
unsigned int IO::ButtonsHeld()
|
||||||
{
|
{
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IO::ButtonHeld(unsigned int button)
|
bool IO::ButtonHeld(unsigned int button)
|
||||||
{
|
{
|
||||||
return (ButtonsHeld() & button) != 0;
|
return (ButtonsHeld() & button) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int IO::ButtonsPressed()
|
unsigned int IO::ButtonsPressed()
|
||||||
{
|
{
|
||||||
return buttons & (~lastButtons);
|
return buttons & (~lastButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IO::ButtonPressed(unsigned int button)
|
bool IO::ButtonPressed(unsigned int button)
|
||||||
{
|
{
|
||||||
return (ButtonsPressed() & button) != 0;
|
return (ButtonsPressed() & button) != 0;
|
||||||
}
|
}
|
@ -34,34 +34,34 @@ typedef int(*INT_RET_THREE_ARGS)(int x, int y, int *out);
|
|||||||
|
|
||||||
class IO
|
class IO
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IO();
|
IO();
|
||||||
~IO(void);
|
~IO();
|
||||||
|
|
||||||
bool Ready();
|
bool Ready();
|
||||||
void Tick();
|
void Tick();
|
||||||
void ErrorMessage(char *msg);
|
void ErrorMessage(char *msg);
|
||||||
unsigned int ButtonsHeld();
|
unsigned int ButtonsHeld();
|
||||||
unsigned int ButtonsPressed();
|
unsigned int ButtonsPressed();
|
||||||
bool ButtonHeld(unsigned int button);
|
bool ButtonHeld(unsigned int button);
|
||||||
bool ButtonPressed(unsigned int button);
|
bool ButtonPressed(unsigned int button);
|
||||||
private:
|
private:
|
||||||
HMODULE core;
|
HMODULE core;
|
||||||
HMODULE device;
|
HMODULE device;
|
||||||
|
|
||||||
INT_RET_ONE_ARG device_initialize;
|
INT_RET_ONE_ARG device_initialize;
|
||||||
INT_RET_NO_ARGS device_is_initialized;
|
INT_RET_NO_ARGS device_is_initialized;
|
||||||
INT_RET_NO_ARGS device_get_status;
|
INT_RET_NO_ARGS device_get_status;
|
||||||
INT_RET_ONE_ARG device_set_panel_mode;
|
INT_RET_ONE_ARG device_set_panel_mode;
|
||||||
INT_RET_THREE_ARGS device_get_panel_trg_on;
|
INT_RET_THREE_ARGS device_get_panel_trg_on;
|
||||||
INT_RET_THREE_ARGS device_get_panel_trg_off;
|
INT_RET_THREE_ARGS device_get_panel_trg_off;
|
||||||
INT_RET_THREE_ARGS device_get_panel_trg_short_on;
|
INT_RET_THREE_ARGS device_get_panel_trg_short_on;
|
||||||
INT_RET_NO_ARGS device_update;
|
INT_RET_NO_ARGS device_update;
|
||||||
INT_RET_NO_ARGS device_finalize;
|
INT_RET_NO_ARGS device_finalize;
|
||||||
|
|
||||||
log_func log_function;
|
log_func log_function;
|
||||||
|
|
||||||
bool is_ready;
|
bool is_ready;
|
||||||
unsigned int buttons;
|
unsigned int buttons;
|
||||||
unsigned int lastButtons;
|
unsigned int lastButtons;
|
||||||
};
|
};
|
@ -12,105 +12,105 @@ static Menu *globalMenu = NULL;
|
|||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
/* Remember our own instance*/
|
/* Remember our own instance*/
|
||||||
globalModule = hModule;
|
globalModule = hModule;
|
||||||
|
|
||||||
/* Load the original DLL to force dependencies to load.
|
/* Load the original DLL to force dependencies to load.
|
||||||
This must be done BEFORE calling dll_entry_init or
|
This must be done BEFORE calling dll_entry_init or
|
||||||
this menu can't be run with a hook DLL. */
|
this menu can't be run with a hook DLL. */
|
||||||
LoadLibraryA("jubeat.dll");
|
LoadLibraryA("jubeat.dll");
|
||||||
|
|
||||||
/* Initialize the menu before any hooks run so our
|
|
||||||
file operations don't get intercepted. */
|
|
||||||
globalMenu = new Menu(L"games.ini");
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
/* Initialize the menu before any hooks run so our
|
||||||
|
file operations don't get intercepted. */
|
||||||
|
globalMenu = new Menu(L"games.ini");
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" __declspec(dllexport) int __cdecl dll_entry_init(int a1, int a2)
|
extern "C" __declspec(dllexport) int __cdecl dll_entry_init(int a1, int a2)
|
||||||
{
|
{
|
||||||
// Initialize the IO
|
// Initialize the IO
|
||||||
IO *io = new IO();
|
IO *io = new IO();
|
||||||
if (!io->Ready())
|
if (!io->Ready())
|
||||||
{
|
{
|
||||||
// Failed to initialize, give up
|
// Failed to initialize, give up
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the menu
|
// Initialize the menu
|
||||||
Menu *menu = globalMenu;
|
Menu *menu = globalMenu;
|
||||||
if( menu->NumberOfEntries() < 1 )
|
if( menu->NumberOfEntries() < 1 )
|
||||||
{
|
{
|
||||||
io->ErrorMessage("No games configured to launch in games.ini!");
|
io->ErrorMessage("No games configured to launch in games.ini!");
|
||||||
|
|
||||||
delete menu;
|
delete menu;
|
||||||
delete io;
|
delete io;
|
||||||
|
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create menu screen
|
// Create menu screen
|
||||||
Display *display = new Display(globalModule, io, menu);
|
Display *display = new Display(globalModule, io, menu);
|
||||||
|
|
||||||
/* Actual game to load */
|
/* Actual game to load */
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
|
|
||||||
/* It may have taken a long time to init */
|
|
||||||
menu->ResetTimeout();
|
|
||||||
|
|
||||||
// Input loop
|
/* It may have taken a long time to init */
|
||||||
while(true) {
|
menu->ResetTimeout();
|
||||||
io->Tick();
|
|
||||||
menu->Tick();
|
|
||||||
display->Tick();
|
|
||||||
|
|
||||||
/* See if somebody killed the display window */
|
|
||||||
if (display->WasClosed())
|
|
||||||
{
|
|
||||||
io->ErrorMessage("Main window closed, exiting!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check to see if we ran out of time waiting for input */
|
// Input loop
|
||||||
if (menu->ShouldBootDefault())
|
while(true) {
|
||||||
{
|
io->Tick();
|
||||||
io->ErrorMessage("Ran out of time, booting current selection!");
|
menu->Tick();
|
||||||
int entry = display->GetSelectedItem();
|
display->Tick();
|
||||||
path = menu->GetEntryPath(entry);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check to see if the user confirmed a selection */
|
/* See if somebody killed the display window */
|
||||||
if (io->ButtonPressed(BUTTON_16)) {
|
if (display->WasClosed())
|
||||||
int entry = display->GetSelectedItem();
|
{
|
||||||
path = menu->GetEntryPath(entry);
|
io->ErrorMessage("Main window closed, exiting!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Close and free libraries
|
/* Check to see if we ran out of time waiting for input */
|
||||||
delete display;
|
if (menu->ShouldBootDefault())
|
||||||
delete menu;
|
{
|
||||||
delete io;
|
io->ErrorMessage("Ran out of time, booting current selection!");
|
||||||
|
int entry = display->GetSelectedItem();
|
||||||
|
path = menu->GetEntryPath(entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (path != NULL)
|
/* Check to see if the user confirmed a selection */
|
||||||
{
|
if (io->ButtonPressed(BUTTON_16)) {
|
||||||
/* Launch actual game */
|
int entry = display->GetSelectedItem();
|
||||||
system(path);
|
path = menu->GetEntryPath(entry);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return failure so launcher.exe doesn't attempt to
|
// Close and free libraries
|
||||||
// further initialize other threads such as the net thread.
|
delete display;
|
||||||
ExitProcess(0);
|
delete menu;
|
||||||
return 0;
|
delete io;
|
||||||
|
|
||||||
|
if (path != NULL)
|
||||||
|
{
|
||||||
|
/* Launch actual game */
|
||||||
|
system(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return failure so launcher.exe doesn't attempt to
|
||||||
|
// further initialize other threads such as the net thread.
|
||||||
|
ExitProcess(0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" __declspec(dllexport) int __cdecl dll_entry_main()
|
extern "C" __declspec(dllexport) int __cdecl dll_entry_main()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -170,6 +170,10 @@
|
|||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Animation.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Display.cpp"
|
RelativePath=".\Display.cpp"
|
||||||
>
|
>
|
||||||
@ -192,6 +196,10 @@
|
|||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Animation.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Display.h"
|
RelativePath=".\Display.h"
|
||||||
>
|
>
|
||||||
|
@ -5,151 +5,151 @@
|
|||||||
|
|
||||||
Menu::Menu(_TCHAR *inifile)
|
Menu::Menu(_TCHAR *inifile)
|
||||||
{
|
{
|
||||||
/* Read settings */
|
/* Read settings */
|
||||||
settings = LoadSettings( inifile, &num_programs );
|
settings = LoadSettings( inifile, &num_programs );
|
||||||
|
|
||||||
/* For exiting on defaults */
|
/* For exiting on defaults */
|
||||||
ftime(&beginning);
|
ftime(&beginning);
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu::~Menu(void)
|
Menu::~Menu()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::ResetTimeout()
|
void Menu::ResetTimeout()
|
||||||
{
|
{
|
||||||
ftime(&beginning);
|
ftime(&beginning);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::Tick()
|
void Menu::Tick()
|
||||||
{
|
{
|
||||||
ftime(¤t);
|
ftime(¤t);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Menu::ShouldBootDefault()
|
bool Menu::ShouldBootDefault()
|
||||||
{
|
{
|
||||||
ftime(¤t);
|
ftime(¤t);
|
||||||
return (current.time - beginning.time) > TIMEOUT_SECONDS;
|
return (current.time - beginning.time) > TIMEOUT_SECONDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Menu::SecondsLeft()
|
unsigned int Menu::SecondsLeft()
|
||||||
{
|
{
|
||||||
ftime(¤t);
|
ftime(¤t);
|
||||||
int seconds = (int)(TIMEOUT_SECONDS - (current.time - beginning.time));
|
int seconds = (int)(TIMEOUT_SECONDS - (current.time - beginning.time));
|
||||||
return seconds >= 0 ? seconds : 0;
|
return seconds >= 0 ? seconds : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads an INI file with the following format:
|
* Loads an INI file with the following format:
|
||||||
*
|
*
|
||||||
* [Name of game to launch]
|
* [Name of game to launch]
|
||||||
* launch=<location of batch/executable>
|
* launch=<location of batch/executable>
|
||||||
*/
|
*/
|
||||||
launcher_program_t *Menu::LoadSettings( _TCHAR *ini_file, unsigned int *final_length )
|
launcher_program_t *Menu::LoadSettings( _TCHAR *ini_file, unsigned int *final_length )
|
||||||
{
|
{
|
||||||
launcher_program_t *progs = 0;
|
launcher_program_t *progs = 0;
|
||||||
*final_length = 0;
|
*final_length = 0;
|
||||||
unsigned int got_name = 0;
|
unsigned int got_name = 0;
|
||||||
launcher_program_t temp;
|
launcher_program_t temp;
|
||||||
|
|
||||||
// Open the file
|
// Open the file
|
||||||
HANDLE hFile = CreateFile(ini_file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
HANDLE hFile = CreateFile(ini_file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
char buffer[16384];
|
char buffer[16384];
|
||||||
unsigned int eof = 0;
|
unsigned int eof = 0;
|
||||||
unsigned int eol = 0;
|
unsigned int eol = 0;
|
||||||
unsigned int buflen = 0;
|
unsigned int buflen = 0;
|
||||||
|
|
||||||
if (hFile == 0)
|
if (hFile == 0)
|
||||||
{
|
{
|
||||||
return progs;
|
return progs;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset( &temp, 0, sizeof(temp) );
|
memset( &temp, 0, sizeof(temp) );
|
||||||
memset( buffer, 0, sizeof(buffer) );
|
memset( buffer, 0, sizeof(buffer) );
|
||||||
|
|
||||||
while( !eof )
|
while( !eof )
|
||||||
{
|
{
|
||||||
DWORD length;
|
DWORD length;
|
||||||
ReadFile( hFile, buffer + buflen, 1, &length, 0 );
|
ReadFile( hFile, buffer + buflen, 1, &length, 0 );
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
{
|
{
|
||||||
eof = 1;
|
eof = 1;
|
||||||
eol = 1;
|
eol = 1;
|
||||||
}
|
}
|
||||||
else if( *(buffer + buflen) == '\r' )
|
else if( *(buffer + buflen) == '\r' )
|
||||||
{
|
{
|
||||||
/* Ignore \r completely */
|
/* Ignore \r completely */
|
||||||
*(buffer + buflen) = 0;
|
*(buffer + buflen) = 0;
|
||||||
}
|
}
|
||||||
else if( *(buffer + buflen) == '\n' )
|
else if( *(buffer + buflen) == '\n' )
|
||||||
{
|
{
|
||||||
/* End of line */
|
/* End of line */
|
||||||
*(buffer + buflen) = 0;
|
*(buffer + buflen) = 0;
|
||||||
eol = 1;
|
eol = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Valid thing */
|
/* Valid thing */
|
||||||
buflen++;
|
buflen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( eol == 1 )
|
if ( eol == 1 )
|
||||||
{
|
{
|
||||||
/* Process line */
|
/* Process line */
|
||||||
if (buffer[0] == '[' && buffer[buflen - 1] == ']' && buflen > 2)
|
if (buffer[0] == '[' && buffer[buflen - 1] == ']' && buflen > 2)
|
||||||
{
|
{
|
||||||
buffer[buflen - 1] = 0;
|
buffer[buflen - 1] = 0;
|
||||||
char *game = buffer + 1;
|
char *game = buffer + 1;
|
||||||
|
|
||||||
/* Copy this into temp structure */
|
/* Copy this into temp structure */
|
||||||
strcpy_s( temp.name, MAX_GAME_NAME_LENGTH, game );
|
strcpy_s( temp.name, MAX_GAME_NAME_LENGTH, game );
|
||||||
got_name = 1;
|
got_name = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (strncmp(buffer, "launch", 6) == 0) {
|
if (strncmp(buffer, "launch", 6) == 0) {
|
||||||
unsigned int loc = 6;
|
unsigned int loc = 6;
|
||||||
// Find equals sign after space
|
// Find equals sign after space
|
||||||
while (loc < buflen && (buffer[loc] == ' ' || buffer[loc] == '\t')) { loc++; }
|
while (loc < buflen && (buffer[loc] == ' ' || buffer[loc] == '\t')) { loc++; }
|
||||||
if (loc < buflen)
|
if (loc < buflen)
|
||||||
{
|
{
|
||||||
if (buffer[loc] == '=')
|
if (buffer[loc] == '=')
|
||||||
{
|
{
|
||||||
loc++;
|
loc++;
|
||||||
while (loc < buflen && (buffer[loc] == ' ' || buffer[loc] == '\t')) { loc++; }
|
while (loc < buflen && (buffer[loc] == ' ' || buffer[loc] == '\t')) { loc++; }
|
||||||
if (loc < buflen)
|
if (loc < buflen)
|
||||||
{
|
{
|
||||||
char *launch = buffer + loc;
|
char *launch = buffer + loc;
|
||||||
|
|
||||||
if( got_name == 1 )
|
if( got_name == 1 )
|
||||||
{
|
{
|
||||||
/* We have a name to associate with this */
|
/* We have a name to associate with this */
|
||||||
strcpy_s( temp.location, MAX_GAME_LOCATION_LENGTH, launch );
|
strcpy_s( temp.location, MAX_GAME_LOCATION_LENGTH, launch );
|
||||||
got_name = 0;
|
got_name = 0;
|
||||||
|
|
||||||
/* Make a new spot for this, copy in */
|
/* Make a new spot for this, copy in */
|
||||||
(*final_length)++;
|
(*final_length)++;
|
||||||
progs = (launcher_program_t *)realloc( progs, sizeof(launcher_program_t) * (*final_length) );
|
progs = (launcher_program_t *)realloc( progs, sizeof(launcher_program_t) * (*final_length) );
|
||||||
memcpy( progs + ((*final_length) - 1), &temp, sizeof(launcher_program_t) );
|
memcpy( progs + ((*final_length) - 1), &temp, sizeof(launcher_program_t) );
|
||||||
memset( &temp, 0, sizeof(temp) );
|
memset( &temp, 0, sizeof(temp) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset buffer */
|
/* Reset buffer */
|
||||||
if (buflen > 0)
|
if (buflen > 0)
|
||||||
{
|
{
|
||||||
memset( buffer, 0, sizeof(buffer) );
|
memset( buffer, 0, sizeof(buffer) );
|
||||||
buflen = 0;
|
buflen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not end of line anymore */
|
/* Not end of line anymore */
|
||||||
eol = 0;
|
eol = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return progs;
|
return progs;
|
||||||
}
|
}
|
@ -12,29 +12,29 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char location[MAX_GAME_LOCATION_LENGTH + 1];
|
char location[MAX_GAME_LOCATION_LENGTH + 1];
|
||||||
char name[MAX_GAME_NAME_LENGTH + 1];
|
char name[MAX_GAME_NAME_LENGTH + 1];
|
||||||
} launcher_program_t;
|
} launcher_program_t;
|
||||||
|
|
||||||
class Menu
|
class Menu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Menu(_TCHAR *inifile);
|
Menu(_TCHAR *inifile);
|
||||||
~Menu(void);
|
~Menu();
|
||||||
|
|
||||||
unsigned int NumberOfEntries() { return num_programs; }
|
unsigned int NumberOfEntries() { return num_programs; }
|
||||||
char *GetEntryName(unsigned int game) { return settings[game].name; }
|
char *GetEntryName(unsigned int game) { return settings[game].name; }
|
||||||
char *GetEntryPath(unsigned int game) { return settings[game].location; }
|
char *GetEntryPath(unsigned int game) { return settings[game].location; }
|
||||||
|
|
||||||
void Tick();
|
void Tick();
|
||||||
void ResetTimeout();
|
void ResetTimeout();
|
||||||
bool ShouldBootDefault();
|
bool ShouldBootDefault();
|
||||||
unsigned int SecondsLeft();
|
unsigned int SecondsLeft();
|
||||||
private:
|
private:
|
||||||
unsigned int num_programs;
|
unsigned int num_programs;
|
||||||
launcher_program_t *settings;
|
launcher_program_t *settings;
|
||||||
struct timeb beginning;
|
struct timeb beginning;
|
||||||
struct timeb current;
|
struct timeb current;
|
||||||
|
|
||||||
launcher_program_t *LoadSettings( _TCHAR *ini_file, unsigned int *final_length );
|
launcher_program_t *LoadSettings( _TCHAR *ini_file, unsigned int *final_length );
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user