diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..0408664 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Wifilapper \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..28bb10a --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..c7d1c5a --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..7c62b52 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b9d0766 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b85d099 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..0d5175c --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..7e76f0f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.idea/wifilapper-1-master.iml b/.idea/wifilapper-1-master.iml new file mode 100644 index 0000000..ccf83c5 --- /dev/null +++ b/.idea/wifilapper-1-master.iml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..2aa36f1 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,569 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + + + + + + + + + 1423903618498 + 1423903618498 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Android + + + + + + + + + + + + + + + 1.8 + + + + + + + + TestApp + + + + + + + + 1.8 + + + + + + + + + + + + + + + + diff --git a/IOIODiagnostics/IOIODiagnostics.iml b/IOIODiagnostics/IOIODiagnostics.iml new file mode 100644 index 0000000..231821b --- /dev/null +++ b/IOIODiagnostics/IOIODiagnostics.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/IOIOLib/IOIOLib.iml b/IOIOLib/IOIOLib.iml new file mode 100644 index 0000000..7ed8cb6 --- /dev/null +++ b/IOIOLib/IOIOLib.iml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + diff --git a/PitsideConsole/ArtLib/ArtUI.cpp b/PitsideConsole/ArtLib/ArtUI.cpp index 7751685..9a8c2ee 100644 --- a/PitsideConsole/ArtLib/ArtUI.cpp +++ b/PitsideConsole/ArtLib/ArtUI.cpp @@ -128,7 +128,6 @@ bool ArtGetOpenFileName(HWND hWndOwner, LPCTSTR lpszTitle, LPTSTR lpszPath, int } bool ArtGetSaveFileName(HWND hWndOwner, LPCTSTR lpszTitle, LPTSTR lpszPath, int cchPath, LPCTSTR lpszFilter) { - lpszPath[0] = '\0'; OPENFILENAME ofn; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hWndOwner; @@ -139,7 +138,7 @@ bool ArtGetSaveFileName(HWND hWndOwner, LPCTSTR lpszTitle, LPTSTR lpszPath, int ofn.nFilterIndex = 0; ofn.lpstrFile = lpszPath; ofn.nMaxFile = cchPath; - ofn.lpstrFileTitle = NULL; + ofn.lpstrFileTitle = lpszPath; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = lpszTitle; diff --git a/PitsideConsole/ArtLib/ArtUI.h b/PitsideConsole/ArtLib/ArtUI.h index 5d3498a..b20f5a6 100644 --- a/PitsideConsole/ArtLib/ArtUI.h +++ b/PitsideConsole/ArtLib/ArtUI.h @@ -1,370 +1,558 @@ -#pragma once -#include -#include "ArtTools.h" -#include -#include -#include -#include "gl/gl.h" -#include -#include "commctrl.h" - -void DrawGLFilledSquare(double dX, double dY, double dRadius); - -GLuint LoadTextureSDL( const char * filename); - -HRESULT InitGLFont(GLuint* pBase, int iFontSize, HDC hdc); -void KillFont(GLuint base); - - -using namespace std; -class ArtListBox -{ -public: - ArtListBox() - { - } - void Init(HWND hWnd, const vector& lstColumnHeaders, const vector& lstColWidths) - { - DASSERT(lstColumnHeaders.size() == lstColWidths.size()); - - m_hWnd = hWnd; - - m_cColumns = lstColumnHeaders.size(); - if(lstColumnHeaders.size() <= 0) // No data to display - { - RECT rc; - GetClientRect(m_hWnd,&rc); - - LVCOLUMN LvCol = {0}; - LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; - LvCol.pszText=L""; - LvCol.cx=RECT_WIDTH(&rc) - 30; - - SendMessage(m_hWnd,LVM_INSERTCOLUMN,0,(LPARAM)&LvCol); // Insert/Show the coloum - } - else // Data to display - { - LVCOLUMN LvCol = {0}; - LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; - - for(unsigned int x = 0; x < lstColumnHeaders.size(); x++) - { - TCHAR szTemp[MAX_PATH]; - wcsncpy_s(szTemp,lstColumnHeaders[x].c_str(),NUMCHARS(szTemp)); - LvCol.cx=lstColWidths[x]; - LvCol.pszText=szTemp; - SendMessage(m_hWnd,LVM_INSERTCOLUMN,x,(LPARAM)&LvCol); // Insert/Show the coloum - } - } - ListView_SetExtendedListViewStyleEx(m_hWnd, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); - } - void AddString(LPCTSTR lpszString, int iData) - { - TCHAR szString[MAX_PATH]; - wcsncpy_s(szString,lpszString,NUMCHARS(szString)); - - LVITEM lvItem = {0}; - lvItem.mask = LVIF_PARAM | LVIF_TEXT; - lvItem.lParam = iData; - lvItem.pszText = szString; - lvItem.iItem = ListView_GetItemCount(m_hWnd); - lvItem.state = 0; - lvItem.stateMask = -1; - lvItem.cchTextMax = wcslen(szString); - - VERIFY(ListView_InsertItem(m_hWnd,&lvItem) >= 0); - } - void AddStrings(vector lstCols, int iData) - { - DASSERT(lstCols.size() == m_cColumns); - - const int iItem = ListView_GetItemCount(m_hWnd); - - TCHAR szString[MAX_PATH]; - wcsncpy_s(szString,lstCols[0].c_str(),NUMCHARS(szString)); - - { - LVITEM lvItem = {0}; - lvItem.mask = LVIF_PARAM | LVIF_TEXT; - lvItem.lParam = iData; - lvItem.pszText = szString; - lvItem.iItem = iItem; - lvItem.iSubItem = 0; - lvItem.state = 0; - lvItem.stateMask = -1; - lvItem.cchTextMax = wcslen(szString); - VERIFY(ListView_InsertItem(m_hWnd,&lvItem) >= 0); - } - - for(unsigned int x = 0;x < lstCols.size(); x++) - { - TCHAR szString[MAX_PATH]; - wcsncpy_s(szString,lstCols[x].c_str(),NUMCHARS(szString)); - - LVITEM lvItem = {0}; - lvItem.mask = LVIF_TEXT; - lvItem.pszText = szString; - lvItem.iItem = iItem; - lvItem.iSubItem = x; - lvItem.state = 0; - lvItem.stateMask = -1; - lvItem.cchTextMax = wcslen(szString); - - VERIFY(ListView_SetItem(m_hWnd,&lvItem)); - } - } - void Clear() - { - ListView_DeleteAllItems(m_hWnd); - } - int GetPosition() - { - return ListView_GetTopIndex(m_hWnd); - } - void MakeVisible(LPARAM iData) - { - // makes sure that the item containing the LPARAM lParam is visible - LVFINDINFO sfFind = {0}; - sfFind.flags = LVFI_PARAM; - sfFind.lParam = iData; - int ixIndex = ListView_FindItem(m_hWnd,-1,&sfFind); - if(ixIndex >= 0) - { - ListView_EnsureVisible(m_hWnd,ixIndex,FALSE); - } - - } - vector GetSelectedIndices() - { - vector ret; - int ixSelect = -1; - do - { - ixSelect = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixSelect, LVNI_SELECTED | LVNI_BELOW); - if(ixSelect >= 0) ret.push_back(ixSelect); - } while(ixSelect >= 0); - return ret; - } - void SetSelectedData(const set& setData) - { - int ixItem = -1; - do - { - ixItem = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixItem, LVNI_ALL); - if(ixItem >= 0) - { - LVITEM sfItem = {0}; - sfItem.iItem = ixItem; - sfItem.iSubItem = 0; - sfItem.stateMask = LVIS_SELECTED; - sfItem.mask = LVIF_STATE | LVIF_PARAM; - - if(ListView_GetItem(m_hWnd,&sfItem)) - { - DASSERT(sfItem.lParam); - if(setData.find(sfItem.lParam) != end(setData)) - { - // found the item in the selection set, so make it selected - sfItem.state |= LVIS_SELECTED; - sfItem.stateMask |= LVIS_SELECTED; - ListView_SetItem(m_hWnd,&sfItem); - } - else - { - // this item is not supposed to be selected - sfItem.state &= ~LVIS_SELECTED; - sfItem.stateMask &= ~LVIS_SELECTED; - ListView_SetItem(m_hWnd, &sfItem); - } - } - else - { - break; - } - } - } while(ixItem >= 0); - } - set GetSelectedItemsData() const - { - set ret; - int ixSelect = -1; - do - { - ixSelect = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixSelect, LVNI_SELECTED); - if(ixSelect >= 0) - { - LVITEM sfItem = {0}; - sfItem.iItem = ixSelect; - sfItem.iSubItem = 0; - sfItem.stateMask = LVIS_SELECTED; - sfItem.mask = LVIF_STATE | LVIF_PARAM; - - if(ListView_GetItem(m_hWnd,&sfItem)) - { - // found an item! - DASSERT(sfItem.lParam != NULL); - ret.insert(sfItem.lParam); - } - else {DASSERT(FALSE); break;} // Added by KDJ to prevent locks when no data is passed - } - } while(ixSelect >= 0); - - return ret; - } -private: - HWND m_hWnd; - int m_cColumns; // used for debugging -}; - - -#include "gl/gl.h" -#include "gl/glu.h" - -class ArtOpenGLWindow -{ -public: - ArtOpenGLWindow() : m_hdc(NULL), m_hRC(NULL), m_hWnd(NULL), m_iFontSize(12) - { - } - virtual ~ArtOpenGLWindow() - { - DeInit(); - } - void Init(HWND hWnd) - { - m_hWnd = hWnd; - m_hdc = GetDC(hWnd); - - PIXELFORMATDESCRIPTOR pfd; - ZeroMemory( &pfd, sizeof( pfd ) ); - pfd.nSize = sizeof( pfd ); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | - PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cDepthBits = 16; - pfd.iLayerType = PFD_MAIN_PLANE; - int iFormat = ChoosePixelFormat( m_hdc, &pfd ); - SetPixelFormat( m_hdc, iFormat, &pfd ); - m_hRC = wglCreateContext(m_hdc); - - HDC hOldDC = wglGetCurrentDC(); - HGLRC hOldRC = wglGetCurrentContext(); - wglMakeCurrent(m_hdc, m_hRC); - - VERIFY(SUCCEEDED(InitGLFont(&m_uFontBase, m_iFontSize, m_hdc))); - - wglMakeCurrent(hOldDC,hOldRC); - } - void DeInit() - { - //DeInitGLText(); - if(m_hRC != NULL && m_hdc != NULL) - { - wglDeleteContext(m_hRC); - ReleaseDC(m_hWnd, m_hdc); - } - } - HDC OGL_GetDC() {return m_hdc;} - HGLRC OGL_GetRC() {return m_hRC;} - HWND OGL_GetHWnd() const {return m_hWnd;} - BOOL HandleMessage(HWND hWnd, UINT uMsg, LPARAM lParam, WPARAM wParam) - { - switch(uMsg) - { - case WM_MOUSEMOVE: - { - POINT ptLastMouse = m_ptMouse; - RECT rcParent,rcThis; - GetWindowRect(GetParent(m_hWnd),&rcParent); - GetWindowRect(m_hWnd,&rcThis); - m_ptMouse.x = LOWORD(wParam); - m_ptMouse.y = HIWORD(wParam); - - m_ptMouse.x -= (rcThis.left - rcParent.left); - m_ptMouse.y -= (rcThis.top - rcParent.top); - - RECT rcClient; - GetClientRect(m_hWnd, &rcClient); - - RECT rcParentClient; - GetClientRect(GetParent(m_hWnd), &rcParentClient); - // the difference between rcParent and rcParentClient's height will be the height of the title bar - m_ptMouse.y += (RECT_HEIGHT(&rcParent) - RECT_HEIGHT(&rcParentClient)); - m_ptMouse.y = RECT_HEIGHT(&rcClient) - m_ptMouse.y; - bool fLastMouseValid = m_fMouseValid; - m_fMouseValid = m_ptMouse.x >= 0 && m_ptMouse.y >= 0 && m_ptMouse.x < RECT_WIDTH(&rcClient) && m_ptMouse.y < RECT_HEIGHT(&rcClient); - return FALSE; - } - case WM_MOUSELEAVE: - m_fMouseValid = false; - return TRUE; - } - return FALSE; - } - virtual void OGL_Paint() = 0; - - void Refresh() - { - HDC hOldDC = wglGetCurrentDC(); - HGLRC hOldRC = wglGetCurrentContext(); - wglMakeCurrent(m_hdc, m_hRC); - OGL_Paint(); - wglMakeCurrent(hOldDC,hOldRC); - } -protected: - int GetWindowFontSize() const {return m_iFontSize*4/3;} - void DrawText(float flX, float flY, const char* text) const; -public: - bool GetMouse(POINT* ppt) - { - if(m_fMouseValid) - { - *ppt = m_ptMouse; - return true; - } - return false; - } -private: - HDC m_hdc; - HWND m_hWnd; - HGLRC m_hRC; - - // semi-separate stuff about mouse position - POINT m_ptMouse; - bool m_fMouseValid; - - GLuint m_uFontBase; - const int m_iFontSize; -}; - - -class IUI -{ -public: - virtual void NotifyChange(WPARAM wParam, LPARAM lParam) = 0; // note: can be called on any thread - virtual LRESULT DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = 0; - virtual DWORD GetDlgId() const = 0; -}; - -// for n, I recommend using your dialog's resource ID -extern map mapDialogs; -template -INT_PTR CALLBACK MessageDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - return mapDialogs[n]->DlgProc(hWnd,uMsg,wParam,lParam); -} -template -void ArtShowDialog(IUI* pDlg) -{ - mapDialogs[n] = pDlg; - - DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(pDlg->GetDlgId()), NULL, ::MessageDlgProc); -} - -// shows the open file dialog, sticks result in szPath... -// true -> path is good -// false -> was cancelled -bool ArtGetOpenFileName(HWND hWndOwner, LPCTSTR lpszTitle, LPTSTR lpszPath, int cchPath, LPCTSTR lpszFilter); -bool ArtGetSaveFileName(HWND hWndOwner, LPCTSTR lpszTitle, LPTSTR lpszPath, int cchPath, LPCTSTR lpszFilter); \ No newline at end of file +#pragma once +#include +#include "ArtTools.h" +#include +#include +#include +#include "gl/gl.h" +#include +#include "commctrl.h" + +void DrawGLFilledSquare(double dX, double dY, double dRadius); + +GLuint LoadTextureSDL( const char * filename); + +HRESULT InitGLFont(GLuint* pBase, int iFontSize, HDC hdc); +void KillFont(GLuint base); + + +using namespace std; +class ArtListBox +{ +public: + ArtListBox() + { + } + // Initialization routine for Listviews with checkboxes for multiple-select options + void Init2(HWND hWnd, const vector& lstColumnHeaders, const vector& lstColWidths) + { + DASSERT(lstColumnHeaders.size() == lstColWidths.size()); + + m_hWnd = hWnd; + + m_cColumns = lstColumnHeaders.size(); + if(lstColumnHeaders.size() <= 0) // No data to display + { + RECT rc; + GetClientRect(m_hWnd,&rc); + + LVCOLUMN LvCol = {0}; + LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; + LvCol.pszText=L""; + LvCol.cx=RECT_WIDTH(&rc) - 30; + + SendMessage(m_hWnd,LVM_INSERTCOLUMN,0,(LPARAM)&LvCol); // Insert/Show the coloum + } + else // Data to display + { + LVCOLUMN LvCol = {0}; + LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; + + for(unsigned int x = 0; x < lstColumnHeaders.size(); x++) + { + TCHAR szTemp[MAX_PATH]; + wcsncpy_s(szTemp,lstColumnHeaders[x].c_str(),NUMCHARS(szTemp)); + LvCol.cx=lstColWidths[x]; + LvCol.pszText=szTemp; + SendMessage(m_hWnd,LVM_INSERTCOLUMN,x,(LPARAM)&LvCol); // Insert/Show the coloum + } + } + ListView_SetExtendedListViewStyleEx(m_hWnd, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_SHOWSELALWAYS, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_SHOWSELALWAYS); + } + + // Original Listview initialization function for non-checkbox Listviews + void Init(HWND hWnd, const vector& lstColumnHeaders, const vector& lstColWidths) + { + DASSERT(lstColumnHeaders.size() == lstColWidths.size()); + + m_hWnd = hWnd; + + m_cColumns = lstColumnHeaders.size(); + if(lstColumnHeaders.size() <= 0) // No data to display + { + RECT rc; + GetClientRect(m_hWnd,&rc); + + LVCOLUMN LvCol = {0}; + LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; + LvCol.pszText=L""; + LvCol.cx=RECT_WIDTH(&rc) - 30; + + SendMessage(m_hWnd,LVM_INSERTCOLUMN,0,(LPARAM)&LvCol); // Insert/Show the coloum + } + else // Data to display + { + LVCOLUMN LvCol = {0}; + LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; + + for(unsigned int x = 0; x < lstColumnHeaders.size(); x++) + { + TCHAR szTemp[MAX_PATH]; + wcsncpy_s(szTemp,lstColumnHeaders[x].c_str(),NUMCHARS(szTemp)); + LvCol.cx=lstColWidths[x]; + LvCol.pszText=szTemp; + SendMessage(m_hWnd,LVM_INSERTCOLUMN,x,(LPARAM)&LvCol); // Insert/Show the coloum + } + } + ListView_SetExtendedListViewStyleEx(m_hWnd, LVS_EX_FULLROWSELECT | LVS_SHOWSELALWAYS, LVS_EX_FULLROWSELECT | LVS_SHOWSELALWAYS); + } + + void AddString(LPCTSTR lpszString, int iData) + { + TCHAR szString[MAX_PATH]; + wcsncpy_s(szString,lpszString,NUMCHARS(szString)); + + LVITEM lvItem = {0}; + lvItem.mask = LVIF_PARAM | LVIF_TEXT; + lvItem.lParam = iData; + lvItem.pszText = szString; + lvItem.iItem = ListView_GetItemCount(m_hWnd); + lvItem.state = 0; + lvItem.stateMask = -1; + lvItem.cchTextMax = wcslen(szString); + + VERIFY(ListView_InsertItem(m_hWnd,&lvItem) >= 0); + } + + int GetCount() + { + return ListView_GetItemCount(m_hWnd); + } + + // Insert the table row at the specified row number, iItem + void InsertStrings(vector lstCols, int iData, int iItem) + { + DASSERT(lstCols.size() == m_cColumns); + + TCHAR szString[MAX_PATH]; + wcsncpy_s(szString,lstCols[0].c_str(),NUMCHARS(szString)); + + { + LVITEM lvItem = {0}; + lvItem.mask = LVIF_PARAM | LVIF_TEXT; + lvItem.lParam = iData; + lvItem.pszText = szString; + lvItem.iItem = iItem; + lvItem.iSubItem = 0; + lvItem.state = 0; + lvItem.stateMask = -1; + lvItem.cchTextMax = wcslen(szString); + VERIFY(ListView_InsertItem(m_hWnd,&lvItem) >= 0); + } + + for(unsigned int x = 0;x < lstCols.size(); x++) + { + TCHAR szString[MAX_PATH]; + wcsncpy_s(szString,lstCols[x].c_str(),NUMCHARS(szString)); + ListView_SetItemText(m_hWnd, iItem, x, szString); + } + } + + // Add the row at the end of the table + void AddStrings(vector lstCols, int iData) + { + DASSERT(lstCols.size() == m_cColumns); + const int iItem = ListView_GetItemCount(m_hWnd); + + TCHAR szString[MAX_PATH]; + wcsncpy_s(szString,lstCols[0].c_str(),NUMCHARS(szString)); + + { + LVITEM lvItem = {0}; + lvItem.mask = LVIF_PARAM | LVIF_TEXT; + lvItem.lParam = iData; + lvItem.pszText = szString; + lvItem.iItem = iItem; + lvItem.iSubItem = 0; + lvItem.state = 0; + lvItem.stateMask = -1; + lvItem.cchTextMax = wcslen(szString); + VERIFY(ListView_InsertItem(m_hWnd,&lvItem) >= 0); + } + + for(unsigned int x = 0;x < lstCols.size(); x++) + { + TCHAR szString[MAX_PATH]; + wcsncpy_s(szString,lstCols[x].c_str(),NUMCHARS(szString)); + ListView_SetItemText(m_hWnd, iItem, x, szString); + } + } + void Clear() + { + ListView_DeleteAllItems(m_hWnd); + } + int GetPosition() + { + return ListView_GetTopIndex(m_hWnd); + } + void MakeVisible(LPARAM iData) + { + // makes sure that the item containing the LPARAM lParam is visible + LVFINDINFO sfFind = {0}; + sfFind.flags = LVFI_PARAM; + sfFind.lParam = iData; + int ixIndex = ListView_FindItem(m_hWnd,-1,&sfFind); + if(ixIndex >= 0) + { + ListView_EnsureVisible(m_hWnd,ixIndex,FALSE); + } + + } + vector GetSelectedIndices() + { + vector ret; + int ixSelect = -1; + do + { + ixSelect = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixSelect, LVNI_SELECTED | LVNI_BELOW); + if(ixSelect >= 0) ret.push_back(ixSelect); + } while(ixSelect >= 0); + return ret; + } + void SetSelectedData(const set& setData) + { + int ixItem = -1; + do + { + ixItem = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixItem, LVNI_ALL); // Search sequentially through the LV index + if(ixItem >= 0) + { + LVITEM sfItem = {0}; + sfItem.iItem = ixItem; + sfItem.iSubItem = 0; + sfItem.stateMask = LVIS_SELECTED | LVIS_STATEIMAGEMASK; + sfItem.mask = LVIF_STATE | LVIF_PARAM; + + if(ListView_GetItem(m_hWnd,&sfItem)) // If item is exists, let's check it against the setData set for a match + { + DASSERT(sfItem.lParam); + // See if the item is part of the selected set + if( setData.find(sfItem.lParam) != end(setData) ) + { + // found the item in the selection set, so make it selected and checkbox checked + sfItem.state |= LVIS_FOCUSED | LVIS_SELECTED; + sfItem.stateMask |= LVIS_SELECTED | LVIS_STATEIMAGEMASK; + ListView_SetItem(m_hWnd,&sfItem); // Highlight the lap + ListView_SetCheckState(m_hWnd,ixItem,true); // Check the checkbox + } + else + { + // this item is not supposed to be selected + sfItem.state &= ~LVIS_SELECTED & ~LVIS_FOCUSED; + sfItem.stateMask &= ~LVIS_SELECTED & ~LVIS_STATEIMAGEMASK; + ListView_SetItem(m_hWnd, &sfItem); // Unhighlight the lap + ListView_SetCheckState(m_hWnd,ixItem,false); // Uncheck the checkbox + } + } + else + { + break; + } + } + } while(ixItem >= 0); + } + + set GetSelectedItemsData() const // GetSelectedItems for single select Listviews + { + set ret; + int ixSelect = -1; + do + { + ixSelect = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixSelect, LVNI_SELECTED); + if(ixSelect >= 0) + { + LVITEM sfItem = {0}; + sfItem.iItem = ixSelect; + sfItem.iSubItem = 0; + sfItem.stateMask = LVIS_SELECTED | LVIS_STATEIMAGEMASK; + sfItem.mask = LVIF_STATE | LVIF_PARAM; + + if(ListView_GetItem(m_hWnd,&sfItem)) + { + // found an item! + DASSERT(sfItem.lParam != NULL); + ret.insert(sfItem.lParam); + } + else {DASSERT(FALSE); break;} // Added by KDJ to prevent locks when no data is passed + } + } while(ixSelect >= 0); + + return ret; + } + + set GetSelectedItemsData2() const // New version to capture the checkbox selections for multi-select Listviews + { + set ret; + int ixSelect = -1; + int iCount = 0; + int iTotCount = ListView_GetItemCount(m_hWnd); // Returns the number of items in the Listview +/* + // First let's clean up the selected or deselected the items and associated checkboxes + do + { + ixSelect = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixSelect, LVNI_SELECTED); // Go through all of the selected items sequentially +// ixSelect = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixSelect, LVNI_ALL); // Go through all of the LV items sequentially + if(ixSelect >= 0) + { + LVITEM sfItem = {0}; + sfItem.iItem = ixSelect; + sfItem.iSubItem = 0; + sfItem.stateMask = LVIS_SELECTED | LVIS_STATEIMAGEMASK; + sfItem.mask = LVIF_STATE | LVIF_PARAM; + if( ListView_GetItem(m_hWnd,&sfItem) ) // Item exists! + { + if ( ListView_GetItemState(m_hWnd,sfItem.iItem, LVIS_SELECTED) ) // Item is selected + { + // Item is highlighted + ListView_SetCheckState(m_hWnd,sfItem.iItem, true); // Check the checkbox for this item + ListView_SetItemState(m_hWnd,sfItem.iItem, LVIS_SELECTED, LVIS_SELECTED); // Highlight the item + DASSERT(sfItem.lParam != NULL); + ret.insert(sfItem.lParam); // Add the item to the selected Set + } + else if ( !ListView_GetItemState(m_hWnd,sfItem.iItem, LVIS_SELECTED) ) // Item is not highlighted, should not hit this + { + // Item is not highlighted + ListView_SetCheckState(m_hWnd,sfItem.iItem, false); // Uncheck the checkbox for this item + ListView_SetItemState(m_hWnd,sfItem.iItem, ~LVIS_SELECTED, LVIS_SELECTED); // Unhighlight the item + ret.erase(sfItem.lParam); // Remove this item from the set + } + } + else + { + DASSERT(FALSE); + break; + } // Added by KDJ to prevent locks when no data is passed + } + } while(ixSelect >= 0); + // Now let's find any other items that have their checkboxes checked, and add them to the set + for(iCount = 0; iCount < iTotCount; iCount++) // Let's clean up the Checkboxes and Selected items + { + LVITEM sfItem = {0}; + sfItem.iItem = iCount; + sfItem.iSubItem = 0; + sfItem.stateMask = LVIS_SELECTED | LVIS_STATEIMAGEMASK; + sfItem.mask = LVIF_STATE | LVIF_PARAM; + // found an item! + ListView_GetItem(m_hWnd,&sfItem); // Get the details about the item and store the lParam + if(ListView_GetCheckState(m_hWnd,sfItem.iItem)) // Check box is checked, let's highlight the item + { + ListView_SetItemState(m_hWnd,sfItem.iItem, LVIS_SELECTED, LVIS_SELECTED); // Highlight the checked item + DASSERT(sfItem.lParam != NULL); + ret.insert(sfItem.lParam); + } + else if(!ListView_GetCheckState(m_hWnd,sfItem.iItem) ) // Checkbox is not checked, let's unhighlight the item + { + ListView_SetItemState(m_hWnd,sfItem.iItem, ~LVIS_SELECTED, LVIS_SELECTED); // Deselect the highlighted item + DASSERT(sfItem.lParam != NULL); + ret.erase(sfItem.lParam); // Remove this item from the set + } + } +*/ + for(iCount = 0; iCount < iTotCount; iCount++) // Let's clean up the Checkboxes and Selected items + { + LVITEM sfItem = {0}; + sfItem.iItem = iCount; + sfItem.iSubItem = 0; + sfItem.stateMask = LVIS_SELECTED | LVIS_STATEIMAGEMASK; + sfItem.mask = LVIF_STATE | LVIF_PARAM; + // found an item! + ListView_GetItem(m_hWnd,&sfItem); // Get the details about the item and store the lParam + if(ListView_GetCheckState(m_hWnd,sfItem.iItem)) // Check box is checked, let's highlight the item + { + ListView_SetItemState(m_hWnd,sfItem.iItem, LVIS_SELECTED, LVIS_SELECTED); // Highlight the checked item + DASSERT(sfItem.lParam != NULL); + ret.insert(sfItem.lParam); + } + else if(!ListView_GetCheckState(m_hWnd,sfItem.iItem) && ListView_GetItemState(m_hWnd,sfItem.iItem,LVIS_SELECTED)) // Check box is not checked, let's unhighlight this item + { + ListView_SetItemState(m_hWnd,sfItem.iItem, ~LVIS_SELECTED, LVIS_SELECTED); // Unhighlight this item + } + } + + return ret; // Return the set of items + } + + set GetSelectedItemsData3() const // Version to capture the Lap List for multi-select choices more efficiently + { + set ret; + int ixSelect = -1; + do + { + ixSelect = SendMessage(m_hWnd, LVM_GETNEXTITEM, ixSelect, LVNI_SELECTED); + if(ixSelect >= 0) + { + LVITEM sfItem = {0}; + sfItem.iItem = ixSelect; + sfItem.iSubItem = 0; + sfItem.stateMask = LVIS_SELECTED; + sfItem.mask = LVIF_STATE | LVIF_PARAM; + + if(ListView_GetItem(m_hWnd,&sfItem)) + { + // found an item! + DASSERT(sfItem.lParam != NULL); + ret.insert(sfItem.lParam); + } + else {DASSERT(FALSE); break;} // Added by KDJ to prevent locks when no data is passed + } + } while(ixSelect >= 0); + + return ret; // Return the set of items + } + +private: + HWND m_hWnd; + int m_cColumns; // used for debugging +}; + +#include "gl/gl.h" +#include "gl/glu.h" + +class ArtOpenGLWindow +{ +public: + ArtOpenGLWindow() : m_hdc(NULL), m_hRC(NULL), m_hWnd(NULL), m_iFontSize(12) + { + } + virtual ~ArtOpenGLWindow() + { + DeInit(); + } + void Init(HWND hWnd) + { + m_hWnd = hWnd; + m_hdc = GetDC(hWnd); + + PIXELFORMATDESCRIPTOR pfd; + ZeroMemory( &pfd, sizeof( pfd ) ); + pfd.nSize = sizeof( pfd ); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cDepthBits = 16; + pfd.iLayerType = PFD_MAIN_PLANE; + int iFormat = ChoosePixelFormat( m_hdc, &pfd ); + SetPixelFormat( m_hdc, iFormat, &pfd ); + m_hRC = wglCreateContext(m_hdc); + + HDC hOldDC = wglGetCurrentDC(); + HGLRC hOldRC = wglGetCurrentContext(); + wglMakeCurrent(m_hdc, m_hRC); + + VERIFY(SUCCEEDED(InitGLFont(&m_uFontBase, m_iFontSize, m_hdc))); + + wglMakeCurrent(hOldDC,hOldRC); + } + void DeInit() + { + //DeInitGLText(); + if(m_hRC != NULL && m_hdc != NULL) + { + wglDeleteContext(m_hRC); + ReleaseDC(m_hWnd, m_hdc); + } + } + HDC OGL_GetDC() {return m_hdc;} + HGLRC OGL_GetRC() {return m_hRC;} + HWND OGL_GetHWnd() const {return m_hWnd;} + BOOL HandleMessage(HWND hWnd, UINT uMsg, LPARAM lParam, WPARAM wParam) + { + switch(uMsg) + { + case WM_MOUSEMOVE: + { + POINT ptLastMouse = m_ptMouse; + RECT rcParent,rcThis; + GetWindowRect(GetParent(m_hWnd),&rcParent); + GetWindowRect(m_hWnd,&rcThis); + m_ptMouse.x = LOWORD(wParam); + m_ptMouse.y = HIWORD(wParam); + + m_ptMouse.x -= (rcThis.left - rcParent.left); + m_ptMouse.y -= (rcThis.top - rcParent.top); + + RECT rcClient; + GetClientRect(m_hWnd, &rcClient); + + RECT rcParentClient; + GetClientRect(GetParent(m_hWnd), &rcParentClient); + // the difference between rcParent and rcParentClient's height will be the height of the title bar + m_ptMouse.y += (RECT_HEIGHT(&rcParent) - RECT_HEIGHT(&rcParentClient)); + m_ptMouse.y = RECT_HEIGHT(&rcClient) - m_ptMouse.y; + bool fLastMouseValid = m_fMouseValid; + m_fMouseValid = m_ptMouse.x >= 0 && m_ptMouse.y >= 0 && m_ptMouse.x < RECT_WIDTH(&rcClient) && m_ptMouse.y < RECT_HEIGHT(&rcClient); + return FALSE; + } + case WM_MOUSELEAVE: + m_fMouseValid = false; + return TRUE; + } + return FALSE; + } + virtual void OGL_Paint() = 0; + + void Refresh() + { + HDC hOldDC = wglGetCurrentDC(); + HGLRC hOldRC = wglGetCurrentContext(); + wglMakeCurrent(m_hdc, m_hRC); + OGL_Paint(); + wglMakeCurrent(hOldDC,hOldRC); + } +protected: + int GetWindowFontSize() const {return m_iFontSize*4/3;} + void DrawText(float flX, float flY, const char* text) const; +public: + bool GetMouse(POINT* ppt) + { + if(m_fMouseValid) + { + *ppt = m_ptMouse; + return true; + } + return false; + } +private: + HDC m_hdc; + HWND m_hWnd; + HGLRC m_hRC; + + // semi-separate stuff about mouse position + POINT m_ptMouse; + bool m_fMouseValid; + + GLuint m_uFontBase; + const int m_iFontSize; +}; + + +class IUI +{ +public: + virtual void NotifyChange(WPARAM wParam, LPARAM lParam) = 0; // note: can be called on any thread + virtual LRESULT DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = 0; + virtual DWORD GetDlgId() const = 0; +}; + +// for n, I recommend using your dialog's resource ID +extern map mapDialogs; +template +INT_PTR CALLBACK MessageDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return mapDialogs[n]->DlgProc(hWnd,uMsg,wParam,lParam); +} +template +void ArtShowDialog(IUI* pDlg) +{ + mapDialogs[n] = pDlg; + + DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(pDlg->GetDlgId()), NULL, ::MessageDlgProc); +} + +// shows the open file dialog, sticks result in szPath... +// true -> path is good +// false -> was cancelled +bool ArtGetOpenFileName(HWND hWndOwner, LPCTSTR lpszTitle, LPTSTR lpszPath, int cchPath, LPCTSTR lpszFilter); +bool ArtGetSaveFileName(HWND hWndOwner, LPCTSTR lpszTitle, LPTSTR lpszPath, int cchPath, LPCTSTR lpszFilter); diff --git a/PitsideConsole/PitsideConsole.sln b/PitsideConsole/PitsideConsole.sln index ac1ffb8..f59215d 100644 --- a/PitsideConsole/PitsideConsole.sln +++ b/PitsideConsole/PitsideConsole.sln @@ -1,63 +1,45 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PitsideConsole", "PitsideConsole\PitsideConsole.vcxproj", "{5091EEA3-E98B-4748-BF4D-6B9D281B7931}" - ProjectSection(ProjectDependencies) = postProject - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B} = {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArtLib", "ArtLib\ArtLib.vcxproj", "{D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}" -EndProject -Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "PitsideConsole_", "Release\PitsideConsole_.exe", "{F69D9218-3460-4995-99F5-393C45152E4F}" - ProjectSection(DebuggerProjectSystem) = preProject - PortSupplier = 00000000-0000-0000-0000-000000000000 - Executable = E:\gitroot\wifilapper\PitsideConsole\Release\PitsideConsole_.exe - RemoteMachine = ARTNEW - StartingDirectory = E:\gitroot\wifilapper\PitsideConsole\Release - Environment = Default - LaunchingEngine = 00000000-0000-0000-0000-000000000000 - LaunchSQLEngine = No - AttachLaunchAction = No - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x86 = Debug|x86 - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|Win32.ActiveCfg = Debug|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|Win32.Build.0 = Debug|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|x86.ActiveCfg = Debug|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|Mixed Platforms.Build.0 = Release|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|Win32.ActiveCfg = Release|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|Win32.Build.0 = Release|Win32 - {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|x86.ActiveCfg = Release|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|Win32.ActiveCfg = Debug|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|Win32.Build.0 = Debug|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|x86.ActiveCfg = Debug|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|Mixed Platforms.Build.0 = Release|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|Win32.ActiveCfg = Release|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|Win32.Build.0 = Release|Win32 - {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|x86.ActiveCfg = Release|Win32 - {F69D9218-3460-4995-99F5-393C45152E4F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {F69D9218-3460-4995-99F5-393C45152E4F}.Debug|Win32.ActiveCfg = Debug|x86 - {F69D9218-3460-4995-99F5-393C45152E4F}.Debug|x86.ActiveCfg = Debug|x86 - {F69D9218-3460-4995-99F5-393C45152E4F}.Release|Mixed Platforms.ActiveCfg = Debug|x86 - {F69D9218-3460-4995-99F5-393C45152E4F}.Release|Win32.ActiveCfg = Debug|x86 - {F69D9218-3460-4995-99F5-393C45152E4F}.Release|x86.ActiveCfg = Debug|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PitsideConsole", "PitsideConsole\PitsideConsole.vcxproj", "{5091EEA3-E98B-4748-BF4D-6B9D281B7931}" + ProjectSection(ProjectDependencies) = postProject + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B} = {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArtLib", "ArtLib\ArtLib.vcxproj", "{D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x86 = Debug|x86 + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|Win32.ActiveCfg = Debug|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|Win32.Build.0 = Debug|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Debug|x86.ActiveCfg = Debug|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|Mixed Platforms.Build.0 = Release|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|Win32.ActiveCfg = Release|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|Win32.Build.0 = Release|Win32 + {5091EEA3-E98B-4748-BF4D-6B9D281B7931}.Release|x86.ActiveCfg = Release|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|Win32.ActiveCfg = Debug|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|Win32.Build.0 = Debug|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Debug|x86.ActiveCfg = Debug|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|Mixed Platforms.Build.0 = Release|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|Win32.ActiveCfg = Release|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|Win32.Build.0 = Release|Win32 + {D18EBEAA-1DDF-4898-8BC1-286BFB5BFA7B}.Release|x86.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PitsideConsole/PitsideConsole/DashWare.cpp b/PitsideConsole/PitsideConsole/DashWare.cpp index 99171c3..6c50fd7 100644 --- a/PitsideConsole/PitsideConsole/DashWare.cpp +++ b/PitsideConsole/PitsideConsole/DashWare.cpp @@ -12,10 +12,10 @@ namespace DashWare { return lap1->GetStartTime() < lap2->GetStartTime(); } - void WriteChannelHeaders(wofstream& out, const vector& lstLaps, map& mapData) + void WriteChannelHeaders(wofstream& out, map& mapData) { // if you update this function, update the dashware.xml file too! - out<::iterator i = begin(mapData); i != end(mapData); i++) @@ -23,124 +23,122 @@ namespace DashWare TCHAR szDataChannelName[MAX_PATH]; const DATA_CHANNEL eChannel = i->first; GetDataChannelName(eChannel, szDataChannelName, NUMCHARS(szDataChannelName)); - out<<","<& lstLaps) + // Subprogram saves the chosen lap's data out to a CSV file for import into rendering programs like Dashware and RaceRender + HRESULT SaveToDashware(LPCTSTR lpszFilename, const vector& lstLaps, vector lstLaps1) { - if(lstLaps.size() <= 0) return E_FAIL; + // lstLaps: Vector of chosen laps to output, lpszFileaname: Filename to output CSV file to + if(lstLaps.size() <= 0) return E_FAIL; - vector lstSortedLaps = lstLaps; - sort(begin(lstSortedLaps),end(lstSortedLaps),SortLapsByTime); + vector lstSortedLaps = lstLaps; // Get all of the chosen laps, lstLaps is used to remove Reference Lap from the list + sort(begin(lstSortedLaps),end(lstSortedLaps),SortLapsByTime); // Sort all of the chosen laps by lap time wofstream out; - out.open(lpszFilename); + out.open(lpszFilename); // Open up the CSV file for input - map mapChannels; - - for(int ixLap = 0;ixLap < lstLaps.size(); ixLap++) + map dwMapChannels; // dwMapChannels is the list of Data Channels for all laps + for(int ixLap = 0;ixLap < lstSortedLaps.size(); ixLap++) { - for(int y = 0; y < DATA_CHANNEL_COUNT; y++) - { - const IDataChannel* pChannel = g_pLapDB->GetDataChannel(lstLaps[ixLap]->GetLapId(),(DATA_CHANNEL)y); - DASSERT(pChannel->IsLocked() && pChannel->IsValid()); -// if(pChannel && pChannel->IsLocked() && pChannel->IsValid()) - if(pChannel && pChannel->IsValid()) - { - mapChannels[(DATA_CHANNEL)y] = pChannel; - } - else - { - DASSERT(FALSE); - } - } + // Find all of the populated data channels for this lap + set setLapData = lstLaps1[ixLap]->GetAvailableChannels(); // Load the CExtendedLap data for the lap list + for(set::iterator i = setLapData.begin(); i != setLapData.end(); i++) + { + const IDataChannel* pChannel = lstLaps1[ixLap]->GetChannel(*i); + DASSERT(pChannel->IsValid()); // Ensure that channel doesn't cause execution issues +// DASSERT(pChannel->IsLocked() && pChannel->IsValid()); +// if(pChannel && pChannel->IsLocked() && pChannel->IsValid()) + if(pChannel && pChannel->IsValid()) + { + dwMapChannels[*i] = pChannel; // Add Data Channel to the list + } + else + { + DASSERT(FALSE); + } + } } - - WriteChannelHeaders(out, lstSortedLaps, mapChannels); - - - int msLastLine = 0; - float flStartTime = 0; // start time in seconds; - for(int ixLap = 0; ixLap < lstSortedLaps.size(); ixLap++) + WriteChannelHeaders(out, dwMapChannels); // Put all Data Channel names into the header for the CSV file + + long long msLastLine = 0; // Indexer for pulling correct timestamp data for each data channel + long long msTimeOffset = 0; // Time in ms to offset the Time in seconds column in the CSV offset file; used to fix phone reset issues + // Need to go through the lstSortedLaps sequentially and find each lap in lstLaps1 for output to file + for (int ixLap = 0; ixLap < lstSortedLaps.size(); ixLap++) { - const ILap* pLap = lstSortedLaps[ixLap]; - int msStartTime = INT_MAX; // start time and end time for this lap (gotten by looking at start and end time for data channels) - int msEndTime = -INT_MAX; - - for(int y = 0; y < DATA_CHANNEL_COUNT; y++) - { - const IDataChannel* pChannel = g_pLapDB->GetDataChannel(pLap->GetLapId(),(DATA_CHANNEL)y); - DASSERT(pChannel->IsLocked() && pChannel->IsValid() && pChannel->GetChannelType() == (DATA_CHANNEL)y); -// if(pChannel && pChannel->IsLocked() && pChannel->IsValid()) - if(pChannel && pChannel->IsValid()) - { - mapChannels[(DATA_CHANNEL)y] = pChannel; - } - else - { - DASSERT(FALSE); - } - } - - for(map::iterator i = begin(mapChannels); i != end(mapChannels); i++) - { - const IDataChannel* pDC = mapChannels[i->first]; - if(pDC) - { - msStartTime = min(pDC->GetStartTimeMs(),msStartTime); - msEndTime = max(pDC->GetEndTimeMs(),msEndTime); - } - } - msEndTime = max(msEndTime, msStartTime + pLap->GetTime()*1000); - - const vector& lstPoints = pLap->GetPoints(); - float flRunningAverage[DATA_CHANNEL_COUNT] = {0.0f}; - bool fUseRunningAverage[DATA_CHANNEL_COUNT] = {0}; - fUseRunningAverage[DATA_CHANNEL_X_ACCEL] = true; - fUseRunningAverage[DATA_CHANNEL_Y_ACCEL] = true; - fUseRunningAverage[DATA_CHANNEL_Z_ACCEL] = true; - - for(int msQuery = msStartTime; msQuery < msEndTime; msQuery += 100) - { - if(msQuery > msLastLine) - { - out<::iterator i = begin(mapChannels); i != end(mapChannels); i++) - { - const IDataChannel* pDC = i->second; - if(pDC) - { - float flValue = pDC->GetValue(msQuery); - if(fUseRunningAverage[i->first]) - { - flRunningAverage[i->first] = 0.7*flValue + 0.3*flRunningAverage[i->first]; - } - _snwprintf(szTemp,NUMCHARS(szTemp),L"%5.6f",fUseRunningAverage[i->first] ? flRunningAverage[i->first] : flValue); - out<<","<GetLap()->GetStartTime() == lstSortedLaps[ixLap]->GetStartTime()) + { + // We found the lap. Let's get all of the populated data channels for this lap + + const ILap* pLap = lstLaps1[iFoundLap]->GetLap(); // Get the chosen lap + long long msStartTime = INT_MAX; // start time and end time for this lap (gotten by looking at start and end time for data channels) + long long msEndTime = -INT_MAX; + + const IDataChannel* pDC = lstLaps1[iFoundLap]->GetChannel(DATA_CHANNEL_VELOCITY); // Use the Velocity data channel to set time boundary conditions for this lap + + msStartTime = pDC->GetStartTimeMs(); + msEndTime = max(msEndTime, msStartTime + pLap->GetTime()*1000); + if ((msStartTime + 2000) < msLastLine) // Time stamp for this lap is less than previous lap; possible phone reset. + // Add an offset to following laps for RaceRender to work correctly + { + msTimeOffset = msLastLine + msTimeOffset + 5000 - msStartTime; + } + + const vector& lstPoints = pLap->GetPoints(); // List of points for this lap + float flRunningAverage[DATA_CHANNEL_COUNT] = {0.0f}; + bool fUseRunningAverage[DATA_CHANNEL_COUNT] = {0}; + fUseRunningAverage[DATA_CHANNEL_X_ACCEL] = true; + fUseRunningAverage[DATA_CHANNEL_Y_ACCEL] = true; + fUseRunningAverage[DATA_CHANNEL_Z_ACCEL] = true; + +// for(int msQuery = msStartTime; msQuery < msEndTime; msQuery += 2000) // Increased time movement for debug purposes + for(int msQuery = msStartTime; msQuery < msEndTime; msQuery += 100) + { + // Lap counter + out << ixLap << ","; + // Time + TCHAR szTemp[100] = L"0"; + _snwprintf( szTemp, NUMCHARS(szTemp), L"%6.3f", ((float)(msQuery + msTimeOffset)/1000.0f) ); + out << szTemp << ","; + // Comment + out << pLap->GetComment(); + // For all of the hard coded channels, loop through them to get the data channel value at this point in time + for(map::iterator i = begin(dwMapChannels); i != end(dwMapChannels); i++) + { + const IDataChannel* pDC = lstLaps1[iFoundLap]->GetChannel(i->first);; // Get the data for this lap/channel + if(pDC) + { + float flValue = pDC->GetValue(msQuery); + if(fUseRunningAverage[i->first]) + { + flRunningAverage[i->first] = 0.7*flValue + 0.3*flRunningAverage[i->first]; + } + _snwprintf(szTemp,NUMCHARS(szTemp),L"%5.6f",fUseRunningAverage[i->first] ? flRunningAverage[i->first] : flValue); + // _snwprintf(szTemp, NUMCHARS(szTemp), L"%5.6f", flValue); // Used for debug purposes + out << "," << szTemp; // Output the value to the CSV file + } + else + { + out << "," ; // if this lap didn't include the data channel, skip it + } + } + out << "," << endl << flush; + msLastLine = msQuery; // Index the time in preparation for the next lap + } + break; // We have our informtation, let's get out of the loop and move to the next lap + } + else + { + // Lap was not found, skip and move on + } + } } out.close(); diff --git a/PitsideConsole/PitsideConsole/DashWare.h b/PitsideConsole/PitsideConsole/DashWare.h index eca1c97..dbc8517 100644 --- a/PitsideConsole/PitsideConsole/DashWare.h +++ b/PitsideConsole/PitsideConsole/DashWare.h @@ -8,5 +8,5 @@ using namespace std; namespace DashWare { - HRESULT SaveToDashware(LPCTSTR lpszFilename, const vector& lstLaps); + HRESULT SaveToDashware(LPCTSTR lpszFilename, const vector& lstLaps, vector lstLaps1); } \ No newline at end of file diff --git a/PitsideConsole/PitsideConsole/DlgAbout.cpp b/PitsideConsole/PitsideConsole/DlgAbout.cpp index 9d8c3ed..3c51d95 100644 --- a/PitsideConsole/PitsideConsole/DlgAbout.cpp +++ b/PitsideConsole/PitsideConsole/DlgAbout.cpp @@ -10,9 +10,18 @@ LRESULT CAboutDlg::DlgProc(HWND c_hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { case WM_INITDIALOG: { + HBITMAP hBitmap = (HBITMAP)::LoadImage( GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_SPLASHIMAGE), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE); ConvertStaticToHyperlink(c_hWnd, IDC_LBLMESSAGE6); + HWND hWndSplash = GetDlgItem( c_hWnd, IDC_SPLASHIMAGE ); + SendMessage(hWndSplash,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBitmap); break; } + case WM_RBUTTONDOWN: + case WM_LBUTTONDOWN: + { + EndDialog(c_hWnd,0); + break; + } case WM_COMMAND: { switch(LOWORD(wParam)) diff --git a/PitsideConsole/PitsideConsole/DlgMessage.cpp b/PitsideConsole/PitsideConsole/DlgMessage.cpp index 9f9ac1e..64f104c 100644 --- a/PitsideConsole/PitsideConsole/DlgMessage.cpp +++ b/PitsideConsole/PitsideConsole/DlgMessage.cpp @@ -18,6 +18,8 @@ LRESULT CMessageDlg::DlgProc case WM_INITDIALOG: { // Initialize the send message parameters. + HWND hWndMsg = GetDlgItem(hWnd,IDC_EDTMESSAGE); + SendMessage(hWndMsg, WM_SETTEXT, NUMCHARS(m_pResults->szMessage), (LPARAM)m_pResults->szMessage); TCHAR szTime[100] = L"1"; HWND hWndTime = GetDlgItem(hWnd, IDC_EDTTIME); SendMessage(hWndTime, WM_SETTEXT, NUMCHARS(szTime), (LPARAM)szTime); diff --git a/PitsideConsole/PitsideConsole/DlgPlotSelect.cpp b/PitsideConsole/PitsideConsole/DlgPlotSelect.cpp index f4cbf4b..4df0f87 100644 --- a/PitsideConsole/PitsideConsole/DlgPlotSelect.cpp +++ b/PitsideConsole/PitsideConsole/DlgPlotSelect.cpp @@ -35,7 +35,7 @@ void LoadLaps(ILapReceiver* pReceiver, int m_iRaceId) vector GetAllLaps() { - set setSelectedLaps = m_LapList.GetSelectedItemsData(); + set setSelectedLaps = m_LapList.GetSelectedItemsData3(); vector lstLaps; for(map::const_iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) { @@ -191,9 +191,7 @@ vector GetAllLaps() { case WM_INITDIALOG: { - // Initialize all data channels, if not already set by user. - if (m_sfLapOpts->m_PlotPrefs[1].m_ChannelName[512] == m_sfLapOpts->m_PlotPrefs[0].m_ChannelName[512]) - { + // Initialize all data channels, if not already set by user. InitPlotPrefs(hWnd, lParam); LoadTransformations(*m_sfLapOpts); // Load transformations from "Transformations.txt" file LoadDropDown(hWnd); // Now load those names into drop down list for selection @@ -206,14 +204,9 @@ vector GetAllLaps() SendMessage(hWndComboBox, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); } - } - else - { set setAvailable; SetPlotPrefs(hWnd, setAvailable); - LoadDropDown(hWnd); // Now load those names into drop down list for selection - } - return TRUE; + return TRUE; } case WM_COMMAND: @@ -711,9 +704,6 @@ vector GetAllLaps() // Send CB_GETCURSEL message to get the index of the selected list item. { int ItemIndex = SendMessage((HWND) lParam, (UINT) CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); -// TCHAR ListItem[256]; -// (TCHAR) SendMessage((HWND) lParam, (UINT) CB_GETLBTEXT, (WPARAM) ItemIndex, (LPARAM) ListItem); -// MessageBox(hWnd, (LPCWSTR) ListItem, TEXT("WM_COMMAND"), MB_OK); m_sfLapOpts->m_PlotPrefs[1].fTransAValue = m_sfLapOpts->m_Tranformations[ItemIndex].f_CoeffA; m_sfLapOpts->m_PlotPrefs[1].fTransBValue = m_sfLapOpts->m_Tranformations[ItemIndex].f_CoeffB; m_sfLapOpts->m_PlotPrefs[1].fTransCValue = m_sfLapOpts->m_Tranformations[ItemIndex].f_CoeffC; diff --git a/PitsideConsole/PitsideConsole/DlgPlotSelect.h b/PitsideConsole/PitsideConsole/DlgPlotSelect.h index 96ee479..a082cd5 100644 --- a/PitsideConsole/PitsideConsole/DlgPlotSelect.h +++ b/PitsideConsole/PitsideConsole/DlgPlotSelect.h @@ -40,6 +40,8 @@ struct PITSIDE_SETTINGS iVelocity = 1; iMapLines = 1; iColorScheme = 0; + bSmoothYesNo = false; + bXAxis_KM = false; } int fRunHTTP; @@ -47,6 +49,8 @@ struct PITSIDE_SETTINGS int iVelocity; int iMapLines; int iColorScheme; + bool bSmoothYesNo; + bool bXAxis_KM; }; struct TRANSFORMATION @@ -66,20 +70,38 @@ struct TRANSFORMATION float f_CoeffC; bool b_LoadTrans; }; - +/* +enum UNIT_PREFERENCE +{ + UNIT_PREFERENCE_KMH, + UNIT_PREFERENCE_MPH, + UNIT_PREFERENCE_MS, + + UNIT_PREFERENCE_COUNT, +}; +*/ enum LAPSORTSTYLE { SORTSTYLE_BYTIMEOFRACE, // sort by the time the lap was done: 2:31pm comes before 4:45pm (well... on the same day) SORTSTYLE_BYLAPTIME, // sort by lap time. 1:12.15 comes before 1:13.45 }; + +enum ORIENTATION // These are phone orientatino ENUMS, for setting up the Traction Circle display inside LapPainter.cpp +{ + VERTICAL_LANDSCAPE, + VERTICAL_PORTRAIT, + FLAT_LANDSCAPE, + FLAT_PORTRAIT +}; struct LAPSUPPLIEROPTIONS { public: - LAPSUPPLIEROPTIONS() : eUnitPreference(UNIT_PREFERENCE_MPH),fDrawSplitPoints(false),fDrawGuides(true),fDrawLines(true),fColorScheme(false),fIOIOHardcoded(true),flWindowShiftX(0),flWindowShiftY(0),iZoomLevels(0),bTractionCircle(false) + LAPSUPPLIEROPTIONS() : eUnitPreference(UNIT_PREFERENCE_MPH),bXAxis_KM(false),fDrawSplitPoints(false),fDrawGuides(true),fDrawLines(true),fColorScheme(false),fIOIOHardcoded(true),flWindowShiftX(0),flWindowShiftY(0),iZoomLevels(0),bTractionCircle(false),bShowReferenceLap(true),e_Orientation(VERTICAL_LANDSCAPE), b_Button_LiveData(true) { } UNIT_PREFERENCE eUnitPreference; + bool bXAxis_KM; bool fDrawSplitPoints; bool fDrawGuides; bool fDrawLines; // whether to draw lines between data points @@ -95,6 +117,11 @@ struct LAPSUPPLIEROPTIONS HWND hWndLap[50]; LAPSORTSTYLE eSortPreference; bool bTractionCircle; // Whether or not to display the Traction Circle display + bool bSmoothYesNo; // Whether or not to smooth the accelerometer graphs + bool bShowReferenceLap; // Whether or not the Reference Lap is displayed + ORIENTATION e_Orientation; // Phone orientation when installed in the car + BOOL b_Button_LiveData; // Button for choosing to pause live data collection to allow for data processing + int LapId; }; diff --git a/PitsideConsole/PitsideConsole/DlgRaceNameEdit.cpp b/PitsideConsole/PitsideConsole/DlgRaceNameEdit.cpp index e576832..99a9e21 100644 --- a/PitsideConsole/PitsideConsole/DlgRaceNameEdit.cpp +++ b/PitsideConsole/PitsideConsole/DlgRaceNameEdit.cpp @@ -17,7 +17,9 @@ LRESULT CRenameDlg::DlgProc { case WM_INITDIALOG: { - // Initialize the send message parameters. + // Initialize the send message parameters, and fill in the dialog with the old item for editing. + HWND hWndMsg = GetDlgItem(hWnd,IDC_EDTMESSAGE2); + SendMessageW(hWndMsg, WM_SETTEXT, (WPARAM)m_pResults->szName, (LPARAM)m_pResults->szName); return TRUE; } case WM_COMMAND: @@ -27,15 +29,17 @@ LRESULT CRenameDlg::DlgProc case IDOK: { HWND hWndMsg = GetDlgItem(hWnd,IDC_EDTMESSAGE2); - SendMessage(hWndMsg, WM_GETTEXT, NUMCHARS(m_pResults->szName), (LPARAM)m_pResults->szName); - if(wcslen(m_pResults->szName) > 0) + TCHAR szTemp[MAX_PATH] = {NULL}; + SendMessage(hWndMsg, WM_GETTEXT, NUMCHARS(szTemp), (LPARAM)szTemp); + if(wcslen(szTemp) > 0 && wcscmp( m_pResults->szName, szTemp ) != 0 ) { // User actually entered something. Let's return this for updating. + wcscpy_s( m_pResults->szName, NUMCHARS(m_pResults->szName), szTemp ); // Copy the string to the sfResult pointer m_pResults->fCancelled = false; } else { - // User did not enter anything. Let's not make any changes. + // User did not enter or change anything. Let's not make any changes. m_pResults->fCancelled = true; } EndDialog(hWnd,0); diff --git a/PitsideConsole/PitsideConsole/DlgRaceRerun.h b/PitsideConsole/PitsideConsole/DlgRaceRerun.h index d643e06..f45e93a 100644 --- a/PitsideConsole/PitsideConsole/DlgRaceRerun.h +++ b/PitsideConsole/PitsideConsole/DlgRaceRerun.h @@ -10,8 +10,8 @@ struct RACERERUN_RESULT RACERERUN_RESULT() { fCancelled = false; - iStart = 0; - iEnd = 0; +// iStart = 0; +// iEnd = 0; } bool fCancelled; int iStart; diff --git a/PitsideConsole/PitsideConsole/DlgRaceSelect.cpp b/PitsideConsole/PitsideConsole/DlgRaceSelect.cpp index b78efdd..be55637 100644 --- a/PitsideConsole/PitsideConsole/DlgRaceSelect.cpp +++ b/PitsideConsole/PitsideConsole/DlgRaceSelect.cpp @@ -16,10 +16,10 @@ LRESULT CRaceSelectDlg::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar lstCols.push_back(L"Date"); lstCols.push_back(L"Race Name"); lstCols.push_back(L"Laps"); - lstWidths.push_back(75); + lstWidths.push_back(85); lstWidths.push_back(160); lstWidths.push_back(40); - sfListBox.Init(GetDlgItem(hWnd,IDC_RACE),lstCols,lstWidths); + sfListBox.Init2(GetDlgItem(hWnd,IDC_RACE),lstCols,lstWidths); // gotta set up the list vector lstRaces = m_pLapDB->GetRaces(); @@ -50,7 +50,7 @@ LRESULT CRaceSelectDlg::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar { case IDOK: { - set setSelected = sfListBox.GetSelectedItemsData(); + set setSelected = sfListBox.GetSelectedItemsData2(); if (setSelected.size() > 0) { // Need to find all Race Sessions selected diff --git a/PitsideConsole/PitsideConsole/DlgRaceSelectEdit.cpp b/PitsideConsole/PitsideConsole/DlgRaceSelectEdit.cpp index f96e91e..ca57556 100644 --- a/PitsideConsole/PitsideConsole/DlgRaceSelectEdit.cpp +++ b/PitsideConsole/PitsideConsole/DlgRaceSelectEdit.cpp @@ -21,10 +21,10 @@ LRESULT CRaceSelectEditDlg::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lstCols.push_back(L"Date"); lstCols.push_back(L"Race Name"); lstCols.push_back(L"Laps"); - lstWidths.push_back(75); + lstWidths.push_back(85); lstWidths.push_back(160); lstWidths.push_back(40); - sfListBox.Init(GetDlgItem(hWnd,IDC_RACE),lstCols,lstWidths); + sfListBox.Init2(GetDlgItem(hWnd,IDC_RACE),lstCols,lstWidths); // gotta set up the list vector lstRaces = m_pLapDB->GetRaces(); @@ -55,7 +55,7 @@ LRESULT CRaceSelectEditDlg::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM { case IDOK: { - set set = sfListBox.GetSelectedItemsData(); + set set = sfListBox.GetSelectedItemsData2(); if(set.size() == 1) { MessageBox(NULL,L"Only 1 race session selected\n\nNo changes were made",L"", MB_OK); @@ -84,7 +84,7 @@ LRESULT CRaceSelectEditDlg::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM if(!sfResult.fCancelled) { // Okay they are serious and really want to merge these race sessions - set setSelected = sfListBox.GetSelectedItemsData(); + set setSelected = sfListBox.GetSelectedItemsData2(); if(setSelected.size() == 1) { // Do nothing, only 1 race session chosen @@ -125,12 +125,31 @@ LRESULT CRaceSelectEditDlg::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM { // Let's make sure that the user really wants to do this. RENAMEDLG_RESULT sfResult; + set setSelected = sfListBox.GetSelectedItemsData2(); + if(setSelected.size() >= 1) + { + // Get the current Race Name to insert into edit dialog + for(set::const_iterator i = setSelected.begin(); i != setSelected.end(); i++) + { + // Let's find the race name in the database to display in the edit dialog + vector lstRaces = m_pLapDB->GetRaces(); + + for(int x = 0;x < lstRaces.size(); x++) + { + if( lstRaces[x].raceId == *i) + { + wcscpy_s( sfResult.szName, NUMCHARS(sfResult.szName), lstRaces[x].strName.c_str() ); // Copy the string to the sfResult pointer + break; + } + } + } + } CRenameDlg dlgRaceRename(&sfResult); ArtShowDialog(&dlgRaceRename); if(!sfResult.fCancelled) { // Okay they are serious and really want to rename these race sessions - set setSelected = sfListBox.GetSelectedItemsData(); + set setSelected = sfListBox.GetSelectedItemsData2(); if(setSelected.size() == 0) { // Do nothing, no race sessions chosen diff --git a/PitsideConsole/PitsideConsole/DlgSelectSessions.cpp b/PitsideConsole/PitsideConsole/DlgSelectSessions.cpp index 763edbd..75b20c6 100644 --- a/PitsideConsole/PitsideConsole/DlgSelectSessions.cpp +++ b/PitsideConsole/PitsideConsole/DlgSelectSessions.cpp @@ -15,10 +15,10 @@ LRESULT CDlgSelectSessions::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lstCols.push_back(L"Date"); lstCols.push_back(L"Race Name"); lstCols.push_back(L"Laps"); - lstWidths.push_back(75); + lstWidths.push_back(85); lstWidths.push_back(160); lstWidths.push_back(40); - sfListBox.Init(GetDlgItem(hWnd,IDC_RACE),lstCols,lstWidths); + sfListBox.Init2(GetDlgItem(hWnd,IDC_RACE),lstCols,lstWidths); // gotta set up the list vector lstRaces = m_pLapDB->GetRaces(); @@ -49,7 +49,7 @@ LRESULT CDlgSelectSessions::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM { case IDOK: { - set setSelected = sfListBox.GetSelectedItemsData(); + set setSelected = sfListBox.GetSelectedItemsData2(); if(setSelected.size() > 0) { // Need to find all Race Sessions selected @@ -66,7 +66,13 @@ LRESULT CDlgSelectSessions::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM else { // Do nothing, no race sessions chosen - MessageBox(NULL,L"No race sessions selected\n\nSelect some race sessions and try again",L"", MB_OK); + int iRet = MessageBox(NULL,L"No race sessions selected\n\nDo you want to start a race without any racers?\n\n(Do this if you want to capture the Start and End time markers\nfor Re-Running the race scenario once all data is collected)",L"", MB_YESNO); + if(iRet == IDYES) + { + m_pResults->m_RaceId[0] = -1; // No Race_Id stored, so let's just save the start/end markers + m_pResults->fCancelled = false; + EndDialog(hWnd,0); + } } return TRUE; } diff --git a/PitsideConsole/PitsideConsole/DlgSetSplits.cpp b/PitsideConsole/PitsideConsole/DlgSetSplits.cpp index 51c8768..c5985e8 100644 --- a/PitsideConsole/PitsideConsole/DlgSetSplits.cpp +++ b/PitsideConsole/PitsideConsole/DlgSetSplits.cpp @@ -6,7 +6,6 @@ #include "ArtTools.h" // for FLOATRECT #include "ArtUI.h" // for ArtOpenGLWindow - LRESULT CSetSplitsDlg::DlgProc ( HWND hWnd, @@ -42,10 +41,8 @@ LRESULT CSetSplitsDlg::DlgProc { return 0; } - switch(uMsg) { - case WM_INITDIALOG: { // Get the Start time for the lap and store it @@ -60,7 +57,6 @@ LRESULT CSetSplitsDlg::DlgProc pSF[x].m_pt1 = V2D(m_sfLapOpts->m_SplitPoints[x].m_sfXPoint,m_sfLapOpts->m_SplitPoints[x].m_sfYPoint); pSF[x].m_pt2 = V2D(m_sfLapOpts->m_SplitPoints[x].m_sfXPoint,m_sfLapOpts->m_SplitPoints[x].m_sfYPoint); } - x = FINISH; { const TimePoint2D& p = lstPoints[lstPoints.size()-1]; @@ -70,15 +66,11 @@ LRESULT CSetSplitsDlg::DlgProc pSF[x].m_pt1 = V2D(m_sfLapOpts->m_SplitPoints[x].m_sfXPoint,m_sfLapOpts->m_SplitPoints[x].m_sfYPoint); pSF[x].m_pt2 = V2D(m_sfLapOpts->m_SplitPoints[x].m_sfXPoint,m_sfLapOpts->m_SplitPoints[x].m_sfYPoint); } - // Show the split points m_sfLapOpts->fDrawSplitPoints = true; - // The the OGL handle p_sfRefLapPainter.Init(hWnd_OGL); - p_sfRefLapPainter.DrawLapLines(*m_sfLapOpts); // draws laps as a map - return TRUE; } /* case WM_MOUSEMOVE: @@ -163,72 +155,56 @@ LRESULT CSetSplitsDlg::DlgProc { // Get the Finish time for the lap and store it and fill in the S/F vectors for this lap GetSplitPoint(SPLIT1, szTempSplit, hWnd); - m_sfLapOpts->fDrawSplitPoints = true; - return TRUE; } case IDC_SETSPLIT2: { // Get the Finish time for the lap and store it and fill in the S/F vectors for this lap GetSplitPoint(SPLIT2, szTempSplit, hWnd); - m_sfLapOpts->fDrawSplitPoints = true; - return TRUE; } case IDC_SETSPLIT3: { // Get the Finish time for the lap and store it and fill in the S/F vectors for this lap GetSplitPoint(SPLIT3, szTempSplit, hWnd); - m_sfLapOpts->fDrawSplitPoints = true; - return TRUE; } case IDC_SETSPLIT4: { // Get the Finish time for the lap and store it and fill in the S/F vectors for this lap GetSplitPoint(SPLIT4, szTempSplit, hWnd); - m_sfLapOpts->fDrawSplitPoints = true; - return TRUE; } case IDC_SETSPLIT5: { // Get the Finish time for the lap and store it and fill in the S/F vectors for this lap GetSplitPoint(SPLIT5, szTempSplit, hWnd); - m_sfLapOpts->fDrawSplitPoints = true; - return TRUE; } case IDC_SETSPLIT6: { // Get the Finish time for the lap and store it and fill in the S/F vectors for this lap GetSplitPoint(SPLIT6, szTempSplit, hWnd); - m_sfLapOpts->fDrawSplitPoints = true; - return TRUE; } case IDC_SETSPLIT7: { // Get the Finish time for the lap and store it and fill in the S/F vectors for this lap GetSplitPoint(SPLIT7, szTempSplit, hWnd); - m_sfLapOpts->fDrawSplitPoints = true; - return TRUE; } case IDC_SETSPLIT8: { // Get the Finish time for the lap and store it and fill in the S/F vectors for this lap GetSplitPoint(SPLIT8, szTempSplit, hWnd); - m_sfLapOpts->fDrawSplitPoints = true; - return TRUE; } case IDOK: diff --git a/PitsideConsole/PitsideConsole/DlgSplash.cpp b/PitsideConsole/PitsideConsole/DlgSplash.cpp deleted file mode 100644 index c72a1cc..0000000 --- a/PitsideConsole/PitsideConsole/DlgSplash.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "Stdafx.h" -#include "resource.h" -#include "pitsideconsole.h" -#include "DlgSplash.h" -#include "Hyperlinks.h" - -LRESULT CSplashDlg::DlgProc -( - HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) -{ - switch(uMsg) - { - case WM_INITDIALOG: - { - HBITMAP hBitmap = (HBITMAP)::LoadImage( GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_SPLASHIMAGE), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE); - ConvertStaticToHyperlink(hWnd, IDC_LBLMESSAGE6); - HWND hWndSplash = GetDlgItem( hWnd, IDC_SPLASHIMAGE ); - SendMessage(hWndSplash,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBitmap); - break; - } - case WM_RBUTTONDOWN: - case WM_LBUTTONDOWN: - { - EndDialog(hWnd,0); - break; - } - case WM_COMMAND: - { - switch(LOWORD(wParam)) - { - case IDOK: - { - EndDialog(hWnd,0); - return TRUE; - } - } - break; - } // end WM_COMMAND - case WM_CLOSE: - { - EndDialog(hWnd,0); - return 0; - } - } - return FALSE; -} \ No newline at end of file diff --git a/PitsideConsole/PitsideConsole/DlgSplash.h b/PitsideConsole/PitsideConsole/DlgSplash.h deleted file mode 100644 index d19a973..0000000 --- a/PitsideConsole/PitsideConsole/DlgSplash.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include -#include "artui.h" -#include "resource.h" - -class CSplashDlg : public IUI -{ -public: - CSplashDlg() {}; - virtual ~CSplashDlg() {}; - - virtual void NotifyChange(WPARAM wParam, LPARAM lParam) {DASSERT(FALSE);}; - virtual LRESULT DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - virtual DWORD GetDlgId() const {return IDD_DLGSPLASH;} -private: -}; diff --git a/PitsideConsole/PitsideConsole/DlgTimingScoring.cpp b/PitsideConsole/PitsideConsole/DlgTimingScoring.cpp index 2a18f22..6c151d7 100644 --- a/PitsideConsole/PitsideConsole/DlgTimingScoring.cpp +++ b/PitsideConsole/PitsideConsole/DlgTimingScoring.cpp @@ -8,22 +8,134 @@ #include #include "DlgRaceRerun.h" +// Set up global variables for listview processing static TCHAR szTitle[MAX_PATH]; SCORINGDATA m_ScoringData[50]; +HWND HL_hWnd; +HWND TS_hWnd; +// HWND click_hWnd; +// HWND hWnd; +LVITEM p_HLlvi; // Listview global pointer for Hot Laps +LVITEM p_TSlvi; // Listview global pointer for Race Scoring // Routines for sorting list views by column headers -int CALLBACK CompareListItems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +int CALLBACK CompareHLListItems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) { - BOOL bSortAscending = (lParamSort > 0); - int nColumn = abs(lParamSort) - 1; - - // Just compare the values of lParam1 and lParam2 - in a real application - // you'd do something more useful here, like get the text of the list items - // and compare that, but this is just an example! -// wcscmp(szRaceNameStart, szRaceName); // String comparison function, not sure how to use it here - return bSortAscending ? (lParam1 - lParam2) : (lParam2 - lParam1); + // Get the text of the list items for comparison + LVITEM pitem1 = {NULL}; + LVITEM pitem2 = {NULL}; + TCHAR sz_Result1[512] = {NULL}; + TCHAR sz_Result2[512] = {NULL}; + BOOL result; + BOOL b_TextResult; + BOOL bSortAscending = (lParamSort > 0); // Determines which way to sort the column + int nColumn = abs(lParamSort) - 1; // Then pulls the column number from the same variable + + if ( HL_hWnd ) // Hot Laps listview + { + // Get the text value for the given items and compare them + p_HLlvi.iItem = lParam1; + p_HLlvi.iSubItem =nColumn; + ListView_GetItem(HL_hWnd, (LVITEM*)&p_HLlvi); + swprintf(sz_Result1, p_HLlvi.cchTextMax, L"%s", p_HLlvi.pszText); + p_HLlvi.iItem = lParam2; + p_HLlvi.iSubItem = nColumn; + ListView_GetItem(HL_hWnd, (LVITEM*)&p_HLlvi); + swprintf(sz_Result2, p_HLlvi.cchTextMax, L"%s", p_HLlvi.pszText); + } + +// b_TextResult = wcscmp(sz_Result2, sz_Result1); + b_TextResult = _wcsicmp(sz_Result1, sz_Result2); + if (bSortAscending > 0 && b_TextResult < 0) +// if (bSortAscending && b_TextResult < 0) + { + result = -1 * abs((lParam1 - lParam2)); +// result = (lParam2 - lParam1); + } + else if (bSortAscending > 0 && b_TextResult >= 0) +// else if (bSortAscending && b_TextResult >= 0) + { + result = 1 * abs((lParam1 - lParam2)); +// result = (lParam1 - lParam2); + } + else if (b_TextResult < 0) +// else if (b_TextResult < 0) + { + result = 1 * abs(lParam2 - lParam1); +// result = (lParam1 - lParam2); + } + else + { + result = -1 * abs(lParam2 - lParam1); +// result = (lParam2 - lParam1); + } + +// result = (bSortAscending && b_TextResult < 0) ? -1 : 1; + if (nColumn == 0) + { + result = bSortAscending ? (lParam1 - lParam2) : (lParam2 - lParam1); + } + return result; } -void OnColumnClick(LPNMLISTVIEW pLVInfo) + +int CALLBACK CompareTSListItems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) +{ + // Get the text of the list items for comparison + LVITEM pitem1 = {NULL}; + LVITEM pitem2 = {NULL}; + TCHAR sz_Result1[512] = {NULL}; + TCHAR sz_Result2[512] = {NULL}; + BOOL result; + BOOL b_TextResult; + BOOL bSortAscending = (lParamSort > 0); // Determines which way to sort the column + int nColumn = abs(lParamSort) - 1; // Then pulls the column number from the same variable + + if ( TS_hWnd ) + { + // Get the text value for the given items and compare them + p_TSlvi.iItem = lParam1; + p_TSlvi.iSubItem =nColumn; + p_TSlvi.iItem = lParam2; + p_TSlvi.iSubItem = nColumn; + ListView_GetItem(TS_hWnd, (LVITEM*)&p_TSlvi); + swprintf(sz_Result1, p_TSlvi.cchTextMax, L"%s", p_TSlvi.pszText, p_TSlvi.iSubItem); + ListView_GetItem(TS_hWnd, (LVITEM*)&p_TSlvi); + swprintf(sz_Result2, p_TSlvi.cchTextMax, L"%s", p_TSlvi.pszText, p_TSlvi.iSubItem); + } + else + { + return 0; // Should not hit this + } + +// b_TextResult = wcscmp(sz_Result2, sz_Result1); + b_TextResult = wcscmp(sz_Result1, sz_Result2); + if (bSortAscending > 0 && b_TextResult < 0) + { + result = -1 * abs((lParam1 - lParam2)); + } + else if (bSortAscending > 0 && b_TextResult >= 0) + { + result = 1 * abs((lParam1 - lParam2)); + } + else if (b_TextResult < 0) + { + result = 1 * abs(lParam2 - lParam1); + } + else + { + result = -1 * abs(lParam2 - lParam1); + } + +// result = (bSortAscending && b_TextResult < 0) ? -1 : 1; + if (nColumn == 0) + { + return bSortAscending ? (lParam1 - lParam2) : (lParam2 - lParam1); + } + else + return result; +} + +void OnColumnClick(LPNMLISTVIEW pLVInfo, HWND hWnd) { static int nSortColumn = 0; static BOOL bSortAscending = TRUE; @@ -35,7 +147,7 @@ void OnColumnClick(LPNMLISTVIEW pLVInfo) else { nSortColumn = pLVInfo->iSubItem; - bSortAscending = TRUE; + bSortAscending = !bSortAscending; } // combine sort info into a single value we can send to our sort function @@ -43,13 +155,26 @@ void OnColumnClick(LPNMLISTVIEW pLVInfo) if (!bSortAscending) lParamSort = -lParamSort; +// click_hWnd = pLVInfo->hdr.hwndFrom; +// HL_hWnd = hWnd; +// TS_hWnd = hWnd; +// HL_hWnd = GetDlgItem(hWnd, IDC_RACESCORING); +// TS_hWnd = GetDlgItem(hWnd, IDC_TIMINGSCORING); + // sort list - ListView_SortItems(pLVInfo->hdr.hwndFrom, CompareListItems, lParamSort); + if ( HL_hWnd && pLVInfo->hdr.hwndFrom == HL_hWnd) + ListView_SortItems(pLVInfo->hdr.hwndFrom, CompareHLListItems, lParamSort); + else + ListView_SortItems(pLVInfo->hdr.hwndFrom, CompareTSListItems, lParamSort); + } LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch(uMsg) + static int tmStartRace, tmEndRace; // Variables for setting up receive time / live car position + HL_hWnd = GetDlgItem(hWnd,IDC_TIMINGSCORING); // Hot Laps listview + TS_hWnd = GetDlgItem(hWnd,IDC_RACESCORING); // Race Timing listview + switch(uMsg) { case WM_INITDIALOG: { @@ -59,8 +184,8 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l swprintf(m_ScoringData[i].db_strRaceName, NUMCHARS(m_ScoringData[i].db_strRaceName),L""); swprintf(m_ScoringData[i].db_szTotTime, NUMCHARS(m_ScoringData[i].db_szTotTime),L""); } - tmStartRace = NULL; - tmEndRace = NULL; // Set the initial End Race time to NULL +// tmStartRace = NULL; +// tmEndRace = NULL; // Set the initial End Race time to NULL // Set up the Hot Lap timing list box vector lstCols; vector lstWidths; @@ -72,8 +197,8 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l lstWidths.push_back(210); lstWidths.push_back(85); lstWidths.push_back(85); - HWND Dlg_hWnd = GetDlgItem(hWnd,IDC_TIMINGSCORING); - sfListBox.Init(Dlg_hWnd,lstCols,lstWidths); +// HL_hWnd = GetDlgItem(hWnd,IDC_TIMINGSCORING); // Hot Laps listview + sfListBox.Init(HL_hWnd,lstCols,lstWidths); // Now set up the Scoring list box @@ -85,9 +210,7 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l scoringLstWidths.push_back(30); scoringLstWidths.push_back(145); scoringLstWidths.push_back(95); - HWND DlgScoring_hWnd = GetDlgItem(hWnd,IDC_RACESCORING); - sfListBox.Init(DlgScoring_hWnd,scoringLstCols,scoringLstWidths); - tmStartRace = NULL; // No races started at window initialization + sfListBox.Init(TS_hWnd,scoringLstCols,scoringLstWidths); HWND hWnd_Comment = GetDlgItem(hWnd, IDC_RACE_COMMENT); SetDlgItemText(hWnd, IDC_RACE_COMMENT, szTitle); @@ -97,13 +220,15 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l case WM_NOTIFY: { // check for column click notification and sort the list view accordingly - if ((((LPNMHDR)lParam)->idFrom == IDC_RACESCORING) && (((LPNMHDR)lParam)->code == LVN_COLUMNCLICK)) + if ( ( ((LPNMHDR)lParam)->idFrom == IDC_RACESCORING) && ( ((LPNMHDR)lParam)->code == LVN_COLUMNCLICK) ) { - OnColumnClick((LPNMLISTVIEW)lParam); +// TS_hWnd = GetDlgItem(hWnd,IDC_RACESCORING); + OnColumnClick((LPNMLISTVIEW)lParam, TS_hWnd ); } - else if ((((LPNMHDR)lParam)->idFrom == IDC_TIMINGSCORING) && (((LPNMHDR)lParam)->code == LVN_COLUMNCLICK)) + else if ( ( ((LPNMHDR)lParam)->idFrom == IDC_TIMINGSCORING) && ( ((LPNMHDR)lParam)->code == LVN_COLUMNCLICK) ) { - OnColumnClick((LPNMLISTVIEW)lParam); +// HL_hWnd = GetDlgItem(hWnd,IDC_TIMINGSCORING); + OnColumnClick((LPNMLISTVIEW)lParam, HL_hWnd ); } return TRUE; } @@ -116,7 +241,7 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l TimingScoringProc((LPVOID)&m_szPath, hWnd); if (tmStartRace) { - CRaceScoring((LPVOID) &m_szPath, hWnd); + CRaceScoring((LPVOID) &m_szPath, hWnd, tmStartRace, tmEndRace); } m_pResults->fCancelled = false; return TRUE; @@ -141,6 +266,16 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l } else { + if (tmStartRace > 0) // There is already a time marker stored, verify user wants to change this + { + DWORD dRet = MessageBox(hWnd, L"You already have a race stored!\n\nAre you sure you want to start a new race?\n\nPrevious race results will be lost if you haven't saved them", L"WARNING", MB_YESNO); + if(dRet == IDNO) + { + // Do nothing + m_pResults->fCancelled = true; + return TRUE; + } + } tmEndRace = NULL; // Remove any end of race marker when new race begins. INT format tmStartRace = GetSecondsSince1970(); // Set the start time for this race session. Unixtime in INT format // tmStartRace = 1376100527; // Used for the TestRaces database only @@ -161,6 +296,17 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l { TCHAR szText[MAX_PATH] = {NULL}; TCHAR szTemp[MAX_PATH] = {NULL}; + if (tmEndRace > 0) // There is already a time marker stored, verify user wants to change this + { + DWORD dRet = MessageBox(hWnd, L"You already have a race stored!\n\nAre you sure you want to change the end time for this race?\n\nPrevious race results will be lost if you haven't saved them", L"WARNING", MB_YESNO); + if(dRet == IDNO) + { + // Do nothing + m_pResults->fCancelled = true; + return TRUE; + } + } + tmEndRace = GetSecondsSince1970(); // Set the end time for this race session. Unixtime in INT format // tmEndRace = 1376100699; // Used for the TestRaces database only // swprintf(szText, NUMCHARS(szText), L"Race End = %i", tmEndRace); @@ -174,7 +320,7 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l TimingScoringProc((LPVOID)&m_szPath, hWnd); // Refresh the results one last time if (tmStartRace) { - CRaceScoring((LPVOID) &m_szPath, hWnd); + CRaceScoring((LPVOID) &m_szPath, hWnd, tmStartRace, tmEndRace); } swprintf(szTemp, NUMCHARS(szTemp), szText); @@ -194,8 +340,9 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l int m_RaceId[50] = {NULL}; // Show the race-selection dialog and let the User pick which ones to use on T&S page RACERERUN_RESULT sfResult; - sfResult.iStart = tmStartRace; - sfResult.iEnd = tmEndRace; + if (sfResult.iStart <= 0 || tmStartRace > 0) sfResult.iStart = tmStartRace; + if (sfResult.iEnd <= 0 || tmEndRace > 0) sfResult.iEnd = tmEndRace; + CRaceRerunDlg dlgRace(&sfResult); ArtShowDialog(&dlgRace); @@ -207,7 +354,7 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l TimingScoringProc((LPVOID)&m_szPath, hWnd); // Refresh the results one last time if (tmStartRace) { - CRaceScoring((LPVOID) &m_szPath, hWnd); + CRaceScoring((LPVOID) &m_szPath, hWnd, tmStartRace, tmEndRace); } } return TRUE; @@ -231,15 +378,37 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l { // swprintf(szText, NUMCHARS(szText), L"Race Start = %i\n\nRace End = %i", tmStartRace, tmEndRace); // MessageBox(hWnd, szText, L"Saving", MB_OK); - TCHAR szFilename[MAX_PATH]; - if(ArtGetSaveFileName(hWnd, L"Choose Output file", szFilename, NUMCHARS(szFilename),L"TXT Files (*.txt)\0*.TXT\0\0")) + TCHAR szFilename[MAX_PATH] = {NULL}; + wcscat(szFilename,L"TimingScoring.txt"); + while (true) { - // let's make sure there's a .txt suffix on that bugger. - if(!str_ends_with(szFilename,L".txt")) + if(ArtGetSaveFileName(hWnd, L"Choose Output file", szFilename, NUMCHARS(szFilename),L"TXT Files (*.txt)\0*.TXT\0\0")) + { + // let's make sure there's a .txt suffix on that bugger. + if(!str_ends_with(szFilename,L".txt") && !str_ends_with(szFilename,L".TXT") ) + { + wcsncat(szFilename,L".txt", NUMCHARS(szFilename)); + } + const bool fFileIsNew = !DoesFileExist(szFilename); + if(fFileIsNew) + { + break; // Exit loop, as file name is valid and new + } + else + { + DWORD dwRet = MessageBox(NULL,L"A file already exists with that name.\n\nAre you sure you want to overwrite it?",L"WARNING", MB_APPLMODAL | MB_ICONWARNING | MB_YESNO | MB_TOPMOST | MB_DEFBUTTON2); + if (dwRet == IDYES) + { + break; // User wants to overwrite file, so exit loop and proceed + } + } + } + else { - wcsncat(szFilename,L".txt", NUMCHARS(szFilename)); + return 0; // User cancelled the save operation, so leave subroutine } - + } + // Open up the file and write the information to it wofstream out; out.open(szFilename); @@ -299,7 +468,6 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l m_pResults->fCancelled = false; return TRUE; - } } else { @@ -326,12 +494,13 @@ LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l } // Function calculates the current laps and elapsed time since the race started -DWORD* CDlgTimingScoring::CRaceScoring(LPVOID pv, HWND hWnd) +DWORD* CDlgTimingScoring::CRaceScoring(LPVOID pv, HWND hWnd, int tmStartRace, int tmEndRace) { LPCTSTR lpszPath = (LPCTSTR)pv; CSfArtSQLiteDB sfDB; vector lstTables; - HWND DlgScoring_hWnd = GetDlgItem(hWnd, IDC_RACESCORING); +// HWND DlgScoring_hWnd = GetDlgItem(hWnd, IDC_RACESCORING); +// TS_hWnd = GetDlgItem(hWnd, IDC_RACESCORING); if(SUCCEEDED(sfDB.Open(lpszPath, lstTables, true))) { // Race ID's are stored in the sfResult.m_RaceId structure @@ -481,64 +650,62 @@ DWORD* CDlgTimingScoring::CRaceScoring(LPVOID pv, HWND hWnd) } rec++; // Keep the counter correct } + sfDB.Close(); // Close the file // set up List view items - vector lstPos; - vector lstRaceName; - vector lstLapTimes; - - ListView_DeleteAllItems(DlgScoring_hWnd); // Clear the list before displaying the update + ListView_DeleteAllItems(TS_hWnd); // Clear the list before displaying the update TCHAR szText[MAX_PATH] = {NULL}; int nItem; - LVITEM lvi; +// LVITEM lvi; LPWSTR result; for (nItem = 0; nItem < rec; ++nItem) { - lvi.mask = LVIF_TEXT | LVIF_PARAM; - lvi.iItem = nItem; - lvi.iSubItem = 0; - lvi.lParam = nItem; + p_TSlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_TSlvi.iItem = nItem; + p_TSlvi.iSubItem = 0; + p_TSlvi.lParam = nItem; swprintf(szTemp, NUMCHARS(szTemp), L"%i", m_ScoringData[nItem].db_iRaceId); std::wstring strTemp(szTemp); result = (LPWSTR)strTemp.c_str(); - lvi.pszText = result; - lvi.cchTextMax = wcslen(result); - ListView_InsertItem(DlgScoring_hWnd, &lvi); + p_TSlvi.pszText = result; + p_TSlvi.cchTextMax = wcslen(result); + ListView_InsertItem(TS_hWnd, &p_TSlvi); // set up subitems - lvi.mask = LVIF_TEXT; - lvi.iItem = nItem; + p_TSlvi.mask = LVIF_TEXT; + p_TSlvi.iItem = nItem; - lvi.iSubItem = 1; + p_TSlvi.iSubItem = 1; std::wstring strRace(m_ScoringData[nItem].db_strRaceName); result = (LPWSTR)strRace.c_str(); - lvi.pszText = result; - lvi.cchTextMax = wcslen(result); - ListView_SetItem(DlgScoring_hWnd, &lvi); +// p_TSlvi.lParam = (LPARAM) result; // Try this for LPARAM + p_TSlvi.lParam = nItem; + p_TSlvi.pszText = result; + p_TSlvi.cchTextMax = wcslen(result); + ListView_SetItem(TS_hWnd, &p_TSlvi); - lvi.iSubItem = 2; + p_TSlvi.iSubItem = 2; std::wstring strTotTimes(m_ScoringData[nItem].db_szTotTime); result = (LPWSTR)strTotTimes.c_str(); - lvi.pszText = result; - lvi.cchTextMax = wcslen(result); - ListView_SetItem(DlgScoring_hWnd, &lvi); +// p_TSlvi.lParam = (LPARAM) result; // Try this for LPARAM + p_TSlvi.lParam = nItem; + p_TSlvi.pszText = result; + p_TSlvi.cchTextMax = wcslen(result); + ListView_SetItem(TS_hWnd, &p_TSlvi); } - lstPos.clear(); - lstRaceName.clear(); - lstLapTimes.clear(); } return 0; } -// Function updates the T&S screen for HPDE's and track days, based upon user choices for Race Sessions selected +// Function updates the HotLap screen for HPDE's and track days, based upon user choices for Race Sessions selected DWORD* CDlgTimingScoring::TimingScoringProc(LPVOID pv, HWND hWnd) { LPCTSTR lpszPath = (LPCTSTR)pv; CSfArtSQLiteDB sfDB; vector lstTables; - HWND Dlg_hWnd = GetDlgItem(hWnd, IDC_TIMINGSCORING); +// HL_hWnd = GetDlgItem(hWnd, IDC_TIMINGSCORING); if(SUCCEEDED(sfDB.Open(lpszPath, lstTables, true))) { // Race ID's are stored in the sfResult.m_RaceId structure @@ -576,6 +743,7 @@ DWORD* CDlgTimingScoring::TimingScoringProc(LPVOID pv, HWND hWnd) TCHAR szRaceName[300] = {NULL}; TCHAR szComment[300] = {NULL}; TCHAR szLap[300] = {NULL}; + // Load up all of the HL vectors with data from the database while(sfQuery.Next()) { float flLapTime = 0; @@ -591,52 +759,65 @@ DWORD* CDlgTimingScoring::TimingScoringProc(LPVOID pv, HWND hWnd) lstLapTimes.push_back(szLap); z++; } - HWND Dlg_hWnd = GetDlgItem(hWnd, IDC_TIMINGSCORING); - ListView_DeleteAllItems(Dlg_hWnd); // Clear the list before displaying the update +// HWND HL_hWnd = GetDlgItem(hWnd, IDC_TIMINGSCORING); + ListView_DeleteAllItems(HL_hWnd); // Clear the list before displaying the update ClearHotLaps(); // Clear the Top 40 Hot Laps list before updating TCHAR szText[MAX_PATH] = {NULL}; // set up list view items int nItem; - LVITEM lvi; +// LVITEM p_HLlvi; LPWSTR result; for (nItem = 0; nItem < z - 1; ++nItem) { - lvi.mask = LVIF_TEXT | LVIF_PARAM; - lvi.iItem = nItem; - lvi.iSubItem = 0; - lvi.lParam = nItem; + p_HLlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_HLlvi.iItem = nItem; + p_HLlvi.iSubItem = 0; + p_HLlvi.lParam = nItem; std::wstring strPos(lstPos[nItem]); result = (LPWSTR)strPos.c_str(); - lvi.pszText = result; - lvi.cchTextMax = wcslen(result); - ListView_InsertItem(Dlg_hWnd, &lvi); + p_HLlvi.pszText = result; + p_HLlvi.cchTextMax = wcslen(result); + ListView_InsertItem(HL_hWnd, &p_HLlvi); // set up subitems - lvi.mask = LVIF_TEXT; - lvi.iItem = nItem; + p_HLlvi.mask = LVIF_TEXT; + p_HLlvi.iItem = nItem; - lvi.iSubItem = 1; + p_HLlvi.iSubItem = 1; std::wstring strRace(lstRaceName[nItem]); result = (LPWSTR)strRace.c_str(); - lvi.pszText = result; - lvi.cchTextMax = wcslen(result); - ListView_SetItem(Dlg_hWnd, &lvi); - - lvi.iSubItem = 2; + //From TCHAR to DWORD. +// DWORD dwSomeNum; +// dwSomeNum = wcstod(result, _T('\0')); +// p_HLlvi.lParam = (LPARAM) dwSomeNum; // Try this for LPARAM + p_HLlvi.lParam = nItem; + p_HLlvi.pszText = result; + p_HLlvi.cchTextMax = wcslen(result); + ListView_SetItem(HL_hWnd, &p_HLlvi); + + p_HLlvi.iSubItem = 2; std::wstring strComment(lstComment[nItem]); result = (LPWSTR)strComment.c_str(); - lvi.pszText = result; - lvi.cchTextMax = wcslen(result); - ListView_SetItem(Dlg_hWnd, &lvi); - - lvi.iSubItem = 3; - lvi.pszText = (LPWSTR)&lstLapTimes[nItem]; + //From TCHAR to DWORD. +// dwSomeNum = wcstod(result, _T('\0')); +// p_HLlvi.lParam = (LPARAM) dwSomeNum; // Try this for LPARAM + p_HLlvi.lParam = nItem; + p_HLlvi.pszText = result; + p_HLlvi.cchTextMax = wcslen(result); + ListView_SetItem(HL_hWnd, &p_HLlvi); + + p_HLlvi.iSubItem = 3; + p_HLlvi.pszText = (LPWSTR)&lstLapTimes[nItem]; std::wstring strLapTimes(lstLapTimes[nItem]); result = (LPWSTR)strLapTimes.c_str(); - lvi.pszText = result; - lvi.cchTextMax = wcslen(result); - ListView_SetItem(Dlg_hWnd, &lvi); + //From TCHAR to DWORD. +// dwSomeNum = wcstod(result, _T('\0')); +// p_HLlvi.lParam = (LPARAM) dwSomeNum; // Try this for LPARAM + p_HLlvi.lParam = nItem; + p_HLlvi.pszText = result; + p_HLlvi.cchTextMax = wcslen(result); + ListView_SetItem(HL_hWnd, &p_HLlvi); } // Now load the RACERESULTS vectors with the Top 40 Hot Laps for saving to a text file @@ -663,6 +844,7 @@ DWORD* CDlgTimingScoring::TimingScoringProc(LPVOID pv, HWND hWnd) lstRaceName.clear(); lstComment.clear(); lstLapTimes.clear(); + sfDB.Close(); } return 0; } diff --git a/PitsideConsole/PitsideConsole/DlgTimingScoring.h b/PitsideConsole/PitsideConsole/DlgTimingScoring.h index fd13566..20abb26 100644 --- a/PitsideConsole/PitsideConsole/DlgTimingScoring.h +++ b/PitsideConsole/PitsideConsole/DlgTimingScoring.h @@ -53,7 +53,7 @@ class CDlgTimingScoring : public IUI public: TS_RESULT* m_pResults; DWORD* TimingScoringProc(LPVOID pv, HWND hWnd); - DWORD* CRaceScoring(LPVOID pv, HWND hWnd); + DWORD* CRaceScoring(LPVOID pv, HWND hWnd, int tmStartRace, int tmEndRace); private: ILapReceiver* m_pLapDB; @@ -61,6 +61,5 @@ class CDlgTimingScoring : public IUI TCHAR m_szPath[MAX_PATH]; SELECTSESSIONS_RESULT* m_sfResult; int str_ends_with(const TCHAR * str, const TCHAR * suffix); - int tmStartRace, tmEndRace; // Variables for setting up receive time / live car position void ClearHotLaps(); }; \ No newline at end of file diff --git a/PitsideConsole/PitsideConsole/DlgTractionCircle.cpp b/PitsideConsole/PitsideConsole/DlgTractionCircle.cpp deleted file mode 100644 index ccc15e1..0000000 --- a/PitsideConsole/PitsideConsole/DlgTractionCircle.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "Stdafx.h" -#include "DlgTractionCircle.h" -#include "resource.h" -#include "pitsideconsole.h" -#include "LapPainter.h" -#include "ArtTools.h" // for FLOATRECT -#include "ArtUI.h" // for ArtOpenGLWindow - - - -LRESULT CTractionCircleDlg::DlgProc -(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - int width, height; - - HWND hWnd_OGL = GetDlgItem(hWnd,IDC_TRACTIONCIRCLEMAP2); - float dBestLength = -1; - static float dTimeToHighlight = -1; - static TimePoint2D ptBest; - static MAPHIGHLIGHT mapPt; - POINT m_ptMouse = {0}; - bool m_fMouseValid = false; - - if(p_sfRefLapPainter.HandleMessage(hWnd_OGL,uMsg,wParam,lParam)) - { - return 0; - } - - switch(uMsg) - { - case WM_INITDIALOG: - case WM_CREATE: //window being created - { - -// hDC = GetDC(hWnd); //get current windows device context - // SetupPixelFormat(hDC); //call our pixel format setup function - - // Create rendering context and make it current -// hRC = wglCreateContext(hDC); -// wglMakeCurrent(hDC, hRC); - - // Display the Traction Circle window -// m_sfLapOpts->bTractionCircle = true; - - // Get the OGL handle - p_sfRefLapPainter.Init(hWnd_OGL); - -// p_sfRefLapPainter.DrawLapLines(*m_sfLapOpts); // draws laps as a map - m_eXChannel = (DATA_CHANNEL)DATA_CHANNEL_X_ACCEL; - m_lstYChannels.push_back((DATA_CHANNEL)DATA_CHANNEL_Y_ACCEL); - p_sfRefLapPainter.DrawTractionCircle((const LAPSUPPLIEROPTIONS) *m_sfLapOpts, true); // draws Traction Circle as a separate map - return TRUE; - - default: - break; - return TRUE; - } - case WM_NOTIFY: - { - - p_sfRefLapPainter.DrawTractionCircle(*m_sfLapOpts, true); // draws laps as a map - - NMHDR* notifyHeader = (NMHDR*)lParam; - switch(wParam) - { - case IDC_LAPS: - { - return TRUE; - } - default: - return TRUE; - } - } - case WM_SIZE: - - // Retrieve width and height - height = HIWORD(lParam); - width = LOWORD(lParam); - - // Don't want a divide by 0 - if (height == 0) - { - height = 1; - } - - // Reset the viewport to new dimensions - glViewport(0, 0, width, height); - - // Set current Matrix to projection - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); //reset projection matrix - - // Time to calculate aspect ratio of our window. - - gluPerspective(54.0f, (GLfloat)width/(GLfloat)height, 1.0f, 1000.0f); - - glMatrixMode(GL_MODELVIEW); //set modelview matrix - glLoadIdentity(); //reset modelview matrix - - return 0; - break; - - case WM_COMMAND: - { - break; - } // end WM_COMMAND - case WM_CLOSE: - { - m_pResults->fCancelled = true; - EndDialog(hWnd,0); - break; - } - } -// p_sfRefLapPainter.Refresh(); // Allow the Set Split Point window its own highlighter - return FALSE; -} diff --git a/PitsideConsole/PitsideConsole/DlgTractionCircle.h b/PitsideConsole/PitsideConsole/DlgTractionCircle.h deleted file mode 100644 index 7ad9160..0000000 --- a/PitsideConsole/PitsideConsole/DlgTractionCircle.h +++ /dev/null @@ -1,162 +0,0 @@ -#pragma once - -#include -#include "ArtTools.h" // for FLOATRECT -#include "LapReceiver.h" // for TimePoint2D -#include "ArtUI.h" // for ArtOpenGLWindow -#include "LapData.h" // for CExtendedPoint -#include "resource.h" -#include "LapPainter.h" -#include "PitsideConsole.h" - -struct TRACTIONCIRCLEDLG_RESULT -{ -public: - TRACTIONCIRCLEDLG_RESULT() - { - fCancelled = true; - } - bool fCancelled; -}; - -class CTractionCircleDlg : public IUI, public ILapSupplier -{ -public: - CTractionCircleDlg(ILapReceiver* pLapDB, CExtendedLap* pLap, TRACTIONCIRCLEDLG_RESULT* pResults, int iRaceId, LAPSUPPLIEROPTIONS* i_sfLapOpts) : m_pLap(pLap), m_pResults(pResults), m_iRaceId(iRaceId), m_sfLapOpts(i_sfLapOpts), p_sfRefLapPainter(this,SUPPLIERID_TRACTIONCIRCLEDISPLAY) - { - m_pLapDB = pLapDB; - m_pLap = pLap; - }; - - virtual void NotifyChange(WPARAM wParam, LPARAM lParam) {DASSERT(FALSE);}; - virtual LRESULT DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - virtual DWORD GetDlgId() const {return IDD_TRACTIONCIRCLE;} - - // <-- returns which laps you want painted - virtual vector GetLapsToShow() const - { - vector lstLaps; - lstLaps.push_back(m_pLap); - return lstLaps; - } - // <-- returns all the laps - virtual vector GetAllLaps() const - { - vector lstLaps; - lstLaps.push_back(m_pLap); - return lstLaps; - } - // <-- returns how you want the laps shown: this can be a map or a data plot - virtual LAPDISPLAYSTYLE GetLapDisplayStyle(int iSupplierId) const - { - return LAPDISPLAYSTYLE_MAP; - } - // <-- returns what data channel you want to use for the x-axis - virtual DATA_CHANNEL GetXChannel() const - { - return DATA_CHANNEL_X; - } - // <-- returns what data channels you want to use for the y-axes (can be 1 or more) - virtual vector GetYChannels() const - { - return m_lstYChannels; - } - // <-- returns the actual data channel object for a given lap. - virtual const IDataChannel* GetChannel(int iLapId, DATA_CHANNEL eChannel) const - { - return m_pLapDB->GetDataChannel(iLapId, eChannel); - } - // <-- returns the x and y bounds for all the laps - virtual FLOATRECT GetAllLapsBounds() const - { - FLOATRECT rc; - rc.left = 1e30; - rc.top = -1e30; - rc.bottom = 1e30; - rc.right = -1e30; - - // changed this so it returns the bounds of the reference lap. This way, data-viewing isn't ruined by errant points - // it used to be based on all the laps, but if you had just one messed-up lap it would make viewing pointless - if(m_pLap != NULL) - { - const vector& lstPoints = m_pLap->GetPoints(); - for(int x = 0; x< lstPoints.size(); x++) - { - const TimePoint2D& p = lstPoints[x]; - rc.left = min(rc.left,p.flX); - rc.top = max(rc.top,p.flY); - rc.bottom = min(rc.bottom,p.flY); - rc.right = max(rc.right,p.flX); - } - } - return rc; - } - - // guide-parameter functions - these configure the background horizontal/vertical lines - // <-- returns the position (in the units of whatever data channel you're plotting) of the first line we should draw - virtual float GetGuideStart(DATA_CHANNEL eChannel, float flMin, float flMax) - { - return 0.0f; - } - // <-- returns the position (in the units of whatever data channel you're plotting) of the first line we should draw - virtual float GetGuideStartX(DATA_CHANNEL eChannel, float flMin, float flMax) - { - return 0.0f; - } - // <-- returns the distance between guidelines (in units of whatever data channel you're plotting) - virtual float GetGuideStep(DATA_CHANNEL eChannel, float flMin, float flMax) - { - return 0.0f; - } - // <-- returns the distance between guidelines (in units of whatever data channel you're plotting) - virtual float GetGuideStepX(DATA_CHANNEL eChannel, float flMin, float flMax) - { - return 0.0f; - } - // <-- returns the absolute lowest value we want to display for a given data channel type - virtual float GetDataHardcodedMin(DATA_CHANNEL eChannel) const - { - return 0.0f; - } - // <-- returns the absolute highest value we want to display for a given data channel type - virtual float GetDataHardcodedMax(DATA_CHANNEL eChannel) const - { - return 0.0f; - } - - // highlighting functions - // <-- only call if you are a HighlightSource. Sets the time in milliseconds that should be highlighted. - virtual void SetLapHighlightTime(const CExtendedLap* m_pLap, int iTimeMs) - { - m_mapLapHighlightTimes[m_pLap] = iTimeMs; - } - // <-- gets the time in milliseconds that should be highlighted. - virtual int GetLapHighlightTime(const CExtendedLap* m_pLap) const - { - DASSERT(m_mapLapHighlightTimes.find(m_pLap) != m_mapLapHighlightTimes.end()); // this should have always ended up set from the "master" highlighter. This function is only called by "slave" highlight-users - return m_mapLapHighlightTimes.find(m_pLap)->second; - } - // returns whether the caller should be a lap highlighter (calling SetLapHighlightTime) or a lap highlight-receiver (calling GetLapHighlightTime) - virtual bool IsHighlightSource(int iSupplierId) const - { - return true; // Allow the Set Split Sectors to be highlight source - } - // <-- gets more display options. - virtual const LAPSUPPLIEROPTIONS& GetDisplayOptions() const - { - return *m_sfLapOpts; - } -private: - TRACTIONCIRCLEDLG_RESULT* m_pResults; - int m_iRaceId; - ILapReceiver* m_pLapDB; - LAPSUPPLIEROPTIONS* m_sfLapOpts; - CExtendedLap* m_pLap; - ILapSupplier* m_sfSectorDisplay; - vector m_lstYChannels; - DATA_CHANNEL m_eXChannel; - map m_mapLapHighlightTimes; // stores the highlight times (in milliseconds since phone app start) for each lap. Set from ILapSupplier calls - int m_iSupplierId; - CLapPainter p_sfRefLapPainter; - -}; diff --git a/PitsideConsole/PitsideConsole/DlgWarning.cpp b/PitsideConsole/PitsideConsole/DlgWarning.cpp index 06e4439..837a765 100644 --- a/PitsideConsole/PitsideConsole/DlgWarning.cpp +++ b/PitsideConsole/PitsideConsole/DlgWarning.cpp @@ -14,7 +14,7 @@ LRESULT CWarningDlg::DlgProc(HWND c_hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara swprintf(szMessage, NUMCHARS(szMessage), L"One or more of the alarm limits has been triggered\n\nCheck your Data Value parameters!!\n\nFailing Channel(s): \n%s", m_szYString); HWND hWndWarning = GetDlgItem(c_hWnd, IDC_WARNING1); SendMessage(hWndWarning, WM_SETTEXT, NUMCHARS(szMessage), (LPARAM)szMessage); - MessageBeep(MB_ICONWARNING); + MessageBeep(MB_OK); // Play a warning sound break; } case WM_COMMAND: diff --git a/PitsideConsole/PitsideConsole/Hyperlinks.cpp b/PitsideConsole/PitsideConsole/Hyperlinks.cpp index ca4b613..cbd4dea 100644 --- a/PitsideConsole/PitsideConsole/Hyperlinks.cpp +++ b/PitsideConsole/PitsideConsole/Hyperlinks.cpp @@ -115,7 +115,7 @@ LRESULT CALLBACK _HyperlinkProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM l { // Shell to the website TCHAR lpOpen[MAX_PATH] = L"open"; - TCHAR lpFile[MAX_PATH] = L"https://sites.google.com/site/wifilapper/"; + TCHAR lpFile[MAX_PATH] = L"http://sites.google.com/site/speedfreqapp"; int nShowCmd = SW_RESTORE; // Restore the Help document, if it is minimized or whatever. HINSTANCE Check = ShellExecuteW(hwnd, lpOpen, lpFile, NULL, NULL, nShowCmd); if ((int)Check <= 32) diff --git a/PitsideConsole/PitsideConsole/LapData.cpp b/PitsideConsole/PitsideConsole/LapData.cpp index 4ba3ded..448045f 100644 --- a/PitsideConsole/PitsideConsole/LapData.cpp +++ b/PitsideConsole/PitsideConsole/LapData.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "LapData.h" #include "PitsideConsole.h" +#include "dlgPlotSelect.h" struct PIDDATA @@ -207,28 +208,44 @@ PIDDATA g_rgPIDData[] = }; PIDDATA g_rgIOIOCustomData[] = { - {L"Fuel Level%%","%3.2f"}, - {L"RPM","%5.1f"}, - {L"Throttle Pos","%3.2f"}, - {L"Brake Pos","%3.2f"}, - {L"Clutch Pos","%3.2f"}, - {L"LF Wheelspeed","%3.2f"}, - {L"RF Wheelspeed","%3.2f"}, - {L"LR Wheelspeed","%3.2f"}, - {L"RR Wheelspeed","%3.2f"}, - {L"Exhaust Temp","%3.1f"}, - {L"LF Tire Temp","%3.1f"}, - {L"RF Tire Tempe","%3.1f"}, - {L"LR Tire Tempe","%3.1f"}, - {L"RR Tire Tempe","%3.1f"}, - {L"LF Brake Temp","%3.1f"}, - {L"RF Brake Temp","%3.1f"}, - {L"LR Brake Temp","%3.1f"}, - {L"RR Brake Temp","%3.1f"}, - {L"Oil Pressure","%3.2f"}, - {L"Oil Temp","%3.1f"}, - {L"Coolant Temp","%3.1f"}, - {L"Alt Voltage","%3.2f"}, + {L"Fuel Level%%","%3.2f"}, // 0x301 + {L"RPM","%5.1f"}, // 0x302 + {L"Throttle Pos","%3.2f"}, // 0x303 + {L"Brake Pos","%3.2f"}, // 0x304 + {L"Clutch Pos","%3.2f"}, // 0x305 + {L"LF Wheelspeed","%3.2f"}, // 0x306 + {L"RF Wheelspeed","%3.2f"}, // 0x307 + {L"LR Wheelspeed","%3.2f"}, // 0x308 + {L"RR Wheelspeed","%3.2f"}, // 0x309 + {L"Exhaust Temp","%3.1f"}, // 0x30A + {L"LF Tire Temp","%3.1f"}, // 0x30B + {L"RF Tire Tempe","%3.1f"}, // 0x30C + {L"LR Tire Tempe","%3.1f"}, // 0x30D + {L"RR Tire Tempe","%3.1f"}, // 0x30E + {L"LF Brake Temp","%3.1f"}, // 0x30F + {L"RF Brake Temp","%3.1f"}, // 0x310 + {L"LR Brake Temp","%3.1f"}, // 0x311 + {L"RR Brake Temp","%3.1f"}, // 0x312 + {L"Oil Pressure","%3.2f"}, // 0x313 + {L"Oil Temp","%3.1f"}, // 0x314 + {L"Coolant Temp","%3.1f"}, // 0x315 + {L"Alt Voltage","%3.2f"}, // 0x316 + {L"Air Temp (F)","%3.2f"}, // 0x317 + {L"MAF (V)","%3.2f"}, // 0x318 + {L"O2 Sensor (V)","%3.2f"}, // 0x319 +}; + +PIDDATA g_rgRaceDACData[] = { + {L"RaceDAC A1","%3.2f"}, // 0x401 + {L"RaceDAC A2","%3.2f"}, // 0x402 + {L"RaceDAC A3","%3.2f"}, // 0x403 + {L"RaceDAC A4","%3.2f"}, // 0x404 + {L"RaceDAC A5","%3.2f"}, // 0x405 + {L"RaceDAC A6","%3.2f"}, // 0x406 + {L"RaceDAC A7","%3.2f"}, // 0x407 + {L"RaceDAC A8","%3.2f"}, // 0x408 + {L"RaceDAC D1","%4.1f"}, // 0x409 + {L"RaceDAC D2","%4.1f"}, // 0x40A }; void GetDataChannelName(DATA_CHANNEL eDC, LPTSTR lpszName, int cch) @@ -243,6 +260,7 @@ void GetDataChannelName(DATA_CHANNEL eDC, LPTSTR lpszName, int cch) case DATA_CHANNEL_ELAPSEDTIME: lpszDataName = L"Elapsed Time"; break; case DATA_CHANNEL_LAPTIME_SUMMARY: lpszDataName = L"Lap Time"; break; case DATA_CHANNEL_VELOCITY: lpszDataName = L"Velocity"; break; + case DATA_CHANNEL_VELOCITYDELTA: lpszDataName = L"Vel. Delta"; break; case DATA_CHANNEL_TIMESLIP: lpszDataName = L"Time-slip"; break; case DATA_CHANNEL_X_ACCEL: lpszDataName = L"X accel"; break; case DATA_CHANNEL_Y_ACCEL: lpszDataName = L"Y accel"; break; @@ -250,6 +268,9 @@ void GetDataChannelName(DATA_CHANNEL eDC, LPTSTR lpszName, int cch) case DATA_CHANNEL_TEMP: lpszDataName = L"Temperature"; break; case DATA_CHANNEL_RECEPTION_X: lpszDataName = L"Wifi Dots X"; break; case DATA_CHANNEL_RECEPTION_Y: lpszDataName = L"Wifi Dots Y"; break; + case DATA_CHANNEL_HRM: lpszDataName = L"Heart Rate"; break; + case DATA_CHANNEL_PING: lpszDataName = L"Ping Time"; break; + case DATA_CHANNEL_STRENGTH: lpszDataName = L"Conn. Level"; break; default: if(eDC >= DATA_CHANNEL_IOIOPIN_START && eDC <= DATA_CHANNEL_IOIOPIN_END) { @@ -268,6 +289,22 @@ void GetDataChannelName(DATA_CHANNEL eDC, LPTSTR lpszName, int cch) lpszDataName = L"Ukwn IOIO pin"; } } + else if(eDC >= DATA_CHANNEL_RACEDAC_START && eDC <= DATA_CHANNEL_RACEDAC_END) + { + lpszDataName = ::g_rgRaceDACData[eDC - DATA_CHANNEL_RACEDAC_START].pListDesc; + } + else if(eDC >= DATA_CHANNEL_RACEDACCUSTOM_START && eDC <= DATA_CHANNEL_RACEDACCUSTOM_END) + { + const int custom = eDC - DATA_CHANNEL_RACEDACCUSTOM_START; + if(custom >= 0 && custom < NUMITEMS(g_rgIOIOCustomData)) + { + lpszDataName = ::g_rgIOIOCustomData[custom].pListDesc; + } + else + { + lpszDataName = L"Ukwn RaceDAC pin"; + } + } else { DASSERT(eDC >= DATA_CHANNEL_PID_START && eDC < DATA_CHANNEL_PID_END); @@ -316,7 +353,7 @@ LPCSTR GetUnitText(UNIT_PREFERENCE eUnits) void GetChannelString(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LPSTR lpsz, int cch) { - CASSERT(DATA_CHANNEL_COUNT == 0x401); + CASSERT(DATA_CHANNEL_COUNT == 0x601); switch(eX) { @@ -339,7 +376,22 @@ void GetChannelString(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LP } case DATA_CHANNEL_LAPTIME_SUMMARY: { - sprintf(lpsz, "%4.1fs", flValue); + sprintf(lpsz, "%4.1f", flValue); + break; + } + case DATA_CHANNEL_HRM: + { + sprintf(lpsz, "%4.1fBPM", flValue); + break; + } + case DATA_CHANNEL_PING: + { + sprintf(lpsz, "%4.0fms", flValue); + break; + } + case DATA_CHANNEL_STRENGTH: + { + sprintf(lpsz, "%4.1f", flValue); break; } case DATA_CHANNEL_TIME: @@ -354,6 +406,7 @@ void GetChannelString(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LP } case DATA_CHANNEL_VELOCITY: + case DATA_CHANNEL_VELOCITYDELTA: { LPCSTR lpszUnits = GetUnitText(eUnits); // note: velocity is in m/s, but most humans will like km/h (well... except for americans, but screw them for now) @@ -409,6 +462,16 @@ void GetChannelString(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LP const int custom = eX - DATA_CHANNEL_IOIOCUSTOM_START; sprintf(lpsz,g_rgIOIOCustomData[custom].pDataFormat, flValue); } + else if(eX >= DATA_CHANNEL_RACEDAC_START && eX <= DATA_CHANNEL_RACEDAC_END) + { + const int pin = eX - DATA_CHANNEL_RACEDAC_START; + sprintf(lpsz, "%4.1fV", flValue); + } + else if(eX >= DATA_CHANNEL_RACEDACCUSTOM_START && eX <= DATA_CHANNEL_RACEDACCUSTOM_END) + { + const int custom = eX - DATA_CHANNEL_RACEDACCUSTOM_START; + sprintf(lpsz,g_rgIOIOCustomData[custom].pDataFormat, flValue); + } else { sprintf(lpsz,"%4.1f",flValue); @@ -420,7 +483,7 @@ void GetChannelString(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LP void GetChannelValue(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LPSTR lpsz, int cch) { - CASSERT(DATA_CHANNEL_COUNT == 0x401); + CASSERT(DATA_CHANNEL_COUNT == 0x601); switch(eX) { @@ -440,6 +503,9 @@ void GetChannelValue(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LPS break; } case DATA_CHANNEL_LAPTIME_SUMMARY: + case DATA_CHANNEL_HRM: + case DATA_CHANNEL_PING: + case DATA_CHANNEL_STRENGTH: { sprintf(lpsz, "%4.1f", flValue); break; @@ -455,6 +521,7 @@ void GetChannelValue(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LPS break; } case DATA_CHANNEL_VELOCITY: + case DATA_CHANNEL_VELOCITYDELTA: { // note: velocity is in m/s, but most humans will like km/h (well... except for americans, but screw them for now) sprintf(lpsz, "%4.1f", ConvertSpeed(eUnits,flValue)); @@ -508,6 +575,16 @@ void GetChannelValue(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LPS const int custom = eX - DATA_CHANNEL_IOIOCUSTOM_START; sprintf(lpsz,g_rgIOIOCustomData[custom].pDataFormat, flValue); } + else if(eX >= DATA_CHANNEL_RACEDAC_START && eX <= DATA_CHANNEL_RACEDAC_END) + { + const int pin = eX - DATA_CHANNEL_RACEDAC_START; + sprintf(lpsz, "%4.1f", flValue); + } + else if(eX >= DATA_CHANNEL_RACEDACCUSTOM_START && eX <= DATA_CHANNEL_RACEDACCUSTOM_END) + { + const int custom = eX - DATA_CHANNEL_RACEDACCUSTOM_START; + sprintf(lpsz,g_rgIOIOCustomData[custom].pDataFormat, flValue); + } else { sprintf(lpsz,"%3.2f",flValue); @@ -579,7 +656,7 @@ bool FindClosestTwoPoints(const TimePoint2D& p, int* pixStartIndex, double dInpu void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtendedLap* pReferenceLap, const ILapReceiver* pLapDB, bool fComputeTimeSlip) { if(lstPoints.size() <= 3) return; // Check so that following operations don't choke. - +// if(lstPoints.size() <= 2) return; // Check so that following operations don't choke. // for calculating distance and time-slip, we need the reference lap if(pReferenceLap != NULL) @@ -593,6 +670,7 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende // the distance-from-start/finish for P is thus (percentage) * (d2's distance) + (100 - percentage) * (d1's distance) IDataChannel* pDistance = pLapDB->AllocateDataChannel(); IDataChannel* pVelocity = pLapDB->AllocateDataChannel(); + IDataChannel* pVelocityDelta = pLapDB->AllocateDataChannel(); IDataChannel* pX = pLapDB->AllocateDataChannel(); IDataChannel* pY = pLapDB->AllocateDataChannel(); IDataChannel* pTime = pLapDB->AllocateDataChannel(); @@ -606,6 +684,7 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende pY->Init(GetLap()->GetLapId(), DATA_CHANNEL_Y); pDistance->Init(GetLap()->GetLapId(), DATA_CHANNEL_DISTANCE); pVelocity->Init(GetLap()->GetLapId(), DATA_CHANNEL_VELOCITY); + pVelocityDelta->Init(GetLap()->GetLapId(), DATA_CHANNEL_VELOCITYDELTA); int iStartPoint = 0; for(int x = 0;x < lstPoints.size(); x++) { @@ -641,6 +720,13 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende m_lstPoints.push_back(TimePoint2D(p)); pDistance->AddPoint((int)p.iTime,dThisDistance); pVelocity->AddPoint((int)p.iTime,p.flVelocity); + + // Let's compute the Velocity delta between the Reference and current lap + const IDataChannel* pReferenceVelocityChannel = pReferenceLap->GetChannel(DATA_CHANNEL_VELOCITY); + const double dD1Velocity = pReferenceVelocityChannel->GetValue(sfD1.iTime); + const double dD2Velocity = pReferenceVelocityChannel->GetValue(sfD2.iTime); + const double dRefVelocity = (dD1Velocity * (1-dPercent)) + (dD2Velocity * dPercent); + pVelocityDelta->AddPoint((int)p.iTime,p.flVelocity - (float)dRefVelocity ); // Insert the velocity delta into the vector for this channel } } else @@ -653,6 +739,13 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende m_lstPoints.push_back(TimePoint2D(p)); pDistance->AddPoint((int)p.iTime,dThisDistance); pVelocity->AddPoint((int)p.iTime,p.flVelocity); + + // Let's compute the Velocity delta between the Reference and current lap + const IDataChannel* pReferenceVelocityChannel = pReferenceLap->GetChannel(DATA_CHANNEL_VELOCITY); + const double dD1Velocity = pReferenceVelocityChannel->GetValue(sfD1.iTime); + const double dD2Velocity = pReferenceVelocityChannel->GetValue(sfD2.iTime); + const double dRefVelocity = (dD1Velocity * (1-dPercent)) + (dD2Velocity * dPercent); + pVelocityDelta->AddPoint((int)p.iTime,p.flVelocity - (float)dRefVelocity ); // Insert the velocity delta into the vector for this channel } } @@ -741,6 +834,16 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende pLapDB->FreeDataChannel(pVelocity); pVelocity = NULL; } + if(pVelocityDelta->IsValid()) + { + pVelocityDelta->Lock(); + AddChannel(pVelocityDelta); + } + else + { + pLapDB->FreeDataChannel(pVelocityDelta); + pVelocityDelta = NULL; + } if(fComputeTimeSlip && m_lstPoints.size() > 0) { @@ -795,7 +898,7 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende ixCheck = (ixCheck+1)%cReferenceSize; if(ixCheck == iRefCheckStart) break; // we've done the whole loop } - } + } if(pTimeSlip && pTimeSlip->IsValid()) { @@ -838,6 +941,7 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende IDataChannel* pDistance = pLapDB->AllocateDataChannel(); IDataChannel* pVelocity = pLapDB->AllocateDataChannel(); + IDataChannel* pVelocityDelta = pLapDB->AllocateDataChannel(); IDataChannel* pTimeSlip = pLapDB->AllocateDataChannel(); IDataChannel* pTime = pLapDB->AllocateDataChannel(); IDataChannel* pLapTime = pLapDB->AllocateDataChannel(); @@ -847,6 +951,7 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende pLapTime->Init(GetLap()->GetLapId(), DATA_CHANNEL_ELAPSEDTIME); pLapTimeSummary->Init(GetLap()->GetLapId(), DATA_CHANNEL_LAPTIME_SUMMARY); // Preparing to add Laptime Summary channel for X-axis pVelocity->Init(GetLap()->GetLapId(), DATA_CHANNEL_VELOCITY); + pVelocityDelta->Init(GetLap()->GetLapId(), DATA_CHANNEL_VELOCITYDELTA); pTimeSlip->Init(GetLap()->GetLapId(), DATA_CHANNEL_TIMESLIP); for(int x = 1;x < lstPoints.size(); x++) { @@ -861,26 +966,22 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende pLapTime->AddPoint(p.iTime, (double)iElapsedTime); const double dX = p.flX - ptLast.flX; const double dY = p.flY - ptLast.flY; -/* // Converting from LONG/LAT to distance in meters - double rad = 6371.0f; // earth's mean radius in km - double dLat, dLon, R, lat1, lat2, lon1, lon2; - R = rad; - lat1 = p.flY * 0.0174532925199433; // Convert from degrees to radians - lon1 = p.flX * 0.0174532925199433; - lat2 = ptLast.flY * 0.0174532925199433; - lon2 = ptLast.flX * 0.0174532925199433; - dLat = (lat2 - lat1); - dLon = (lon2 - lon1); - double a = sin(dLat/2) * sin(dLat/2) + cos(lat1) * cos(lat2) * sin(dLon/2) * sin(dLon/2); - double c = 2 * atan2(sqrt(a), sqrt(1-a)); - const double d = R * c * 1000; // Return the distance in meters */ - const double d = sqrt (dY*dY + dX*dX); // Return distance in Theta of Long/Lat. Needed until Jason fixes web-side GUI - dDistance += d; + double d; + if ( SetDistance(-1) ) + { + d = fReturnDistanceInMeters (p, ptLast); // Return the distance in meters + } + else + { + d = sqrt (dY*dY + dX*dX); // Return distance in Theta of Long/Lat. Needed until Jason fixes web-side GUI + } + dDistance += d; m_lstPoints.push_back(TimePoint2D(p)); ptLast = p; pDistance->AddPoint(p.iTime, dDistance); pVelocity->AddPoint(p.iTime, p.flVelocity); + pVelocityDelta->AddPoint(p.iTime, 0); // No delta from reference lap, since we ARE the reference lap pTimeSlip->AddPoint(p.iTime, 0); } @@ -891,12 +992,14 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende pLapTimeSummary->Lock(); pLapTime->Lock(); pVelocity->Lock(); + pVelocityDelta->Lock(); pTimeSlip->Lock(); AddChannel(pDistance); AddChannel(pTime); AddChannel(pLapTime); AddChannel(pLapTimeSummary); AddChannel(pVelocity); + AddChannel(pVelocityDelta); AddChannel(pTimeSlip); AddChannel(pX); AddChannel(pY); @@ -915,6 +1018,24 @@ void CExtendedLap::ComputeLapData(const vector& lstPoints, CExtende } } +const double fReturnDistanceInMeters (const TimePoint2D& p, TimePoint2D ptLast) +{ + // Converting from LONG/LAT to distance in meters + double rad = 6371.0f; // earth's mean radius in km + double dLat, dLon, R, lat1, lat2, lon1, lon2; + R = rad; + lat1 = p.flY * 0.0174532925199433; // Convert from degrees to radians + lon1 = p.flX * 0.0174532925199433; + lat2 = ptLast.flY * 0.0174532925199433; + lon2 = ptLast.flX * 0.0174532925199433; + dLat = (lat2 - lat1); + dLon = (lon2 - lon1); + double a = sin(dLat/2) * sin(dLat/2) + cos(lat1) * cos(lat2) * sin(dLon/2) * sin(dLon/2); + double c = 2 * atan2(sqrt(a), sqrt(1-a)); + const double d = R * c * 1000; // Return the distance in meters + return d; +} + const TimePoint2D GetPointAtTime(const vector& lstPoints, int iTimeMs) { int ixLow = 0; diff --git a/PitsideConsole/PitsideConsole/LapData.h b/PitsideConsole/PitsideConsole/LapData.h index 0ae3d7a..b50fec6 100644 --- a/PitsideConsole/PitsideConsole/LapData.h +++ b/PitsideConsole/PitsideConsole/LapData.h @@ -1,7 +1,9 @@ #pragma once #include -#include "LapReceiver.h" #include "ArtTools.h" // for FormatTimeMinutesSecondsMs +#include "resource.h" +#include "LapReceiver.h" +#include "PitsideConsole.h" using namespace std; enum DATA_CHANNEL @@ -9,13 +11,8 @@ enum DATA_CHANNEL DATA_CHANNEL_START = 0, DATA_CHANNEL_X = DATA_CHANNEL_START, DATA_CHANNEL_Y = 1, - DATA_CHANNEL_PLOTTABLE_START = 2, - DATA_CHANNEL_DISTANCE = DATA_CHANNEL_PLOTTABLE_START, - DATA_CHANNEL_TIME = 11, - DATA_CHANNEL_ELAPSEDTIME = 12, - DATA_CHANNEL_LAPTIME_SUMMARY = 13, DATA_CHANNEL_VELOCITY = 3, DATA_CHANNEL_TIMESLIP = 4, DATA_CHANNEL_X_ACCEL = 5, @@ -24,15 +21,32 @@ enum DATA_CHANNEL DATA_CHANNEL_RECEPTION_X = 8, DATA_CHANNEL_RECEPTION_Y = 9, DATA_CHANNEL_Z_ACCEL = 10, + DATA_CHANNEL_TIME = 11, + DATA_CHANNEL_ELAPSEDTIME = 12, + DATA_CHANNEL_LAPTIME_SUMMARY = 13, + DATA_CHANNEL_VELOCITYDELTA = 14, + DATA_CHANNEL_STRENGTH = 0x11, + DATA_CHANNEL_HRM = 0x80, + DATA_CHANNEL_PING = 0x81, DATA_CHANNEL_PID_START = 0x100, DATA_CHANNEL_PID_END = 0x200, - DATA_CHANNEL_IOIOPIN_START = 0x200, + DATA_CHANNEL_IOIOPIN_START = 0x201, DATA_CHANNEL_IOIOPIN_END = 0x300, DATA_CHANNEL_IOIOCUSTOM_START = 0x301, DATA_CHANNEL_IOIOCUSTOM_END = 0x400, - DATA_CHANNEL_COUNT, + DATA_CHANNEL_RACEDAC_START = 0x401, + DATA_CHANNEL_RACEDAC_END = 0x500, + DATA_CHANNEL_RACEDACCUSTOM_START = 0x501, + DATA_CHANNEL_RACEDACCUSTOM_END = 0x600, + DATA_CHANNEL_COUNT = 0x601, +}; + +enum XAXIS_PREFERENCE +{ + XAXIS_PREFERENCE_LAT, + XAXIS_PREFERENCE_KM, }; enum UNIT_PREFERENCE @@ -42,12 +56,16 @@ enum UNIT_PREFERENCE UNIT_PREFERENCE_MS, UNIT_PREFERENCE_COUNT, -}; +}; + void GetDataChannelName(DATA_CHANNEL eDC, LPTSTR lpszName, int cch); float ConvertSpeed(UNIT_PREFERENCE eConvertTo, float flVelocityInMetersPerSecond); +bool bXAxisUnits(XAXIS_PREFERENCE xConvertTo); LPCSTR GetUnitText(UNIT_PREFERENCE eUnits); void GetChannelString(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LPSTR lpsz, int cch); void GetChannelValue(DATA_CHANNEL eX, UNIT_PREFERENCE eUnits, float flValue, LPSTR lpsz, int cch); +const double fReturnDistanceInMeters (const TimePoint2D& p, TimePoint2D ptLast); +static bool b_Distance; // Whether or not distance is reported in KM or LAT bool FindClosestTwoPoints(const TimePoint2D& p, double dInputPercentage, const vector& lstPoints, TimePoint2D* pt1, TimePoint2D* pt2); @@ -99,6 +117,23 @@ class CExtendedLap swprintf(lpszBuffer, cchBuffer, L"%02d:%02d:%02d - Laptime: %s", m_tmStart.wHour, m_tmStart.wMinute, m_tmStart.wSecond, szTime); } } +static bool SetDistance(int b_KmOrLat) // Function to set X-Axis units in either KM to Latitude/Longitudinal degrees + { + if( b_KmOrLat == -1 ) // Read the existing state of the switch + { + return b_Distance; + } + else if( b_KmOrLat == 1 ) + { + b_Distance = true; + return true; + } + else + { + b_Distance = false; + return false; + } + } static void GetStringHeaders(vector& lstCols, vector& lstWidths) { lstCols.push_back(L"Time"); @@ -118,6 +153,17 @@ class CExtendedLap lstCols.push_back(L"Y-Axis"); lstWidths.push_back(90); } + static void GetStringHeadersDataValues(vector& lstCols, vector& lstWidths) + { + lstCols.push_back(L"Parameter"); + lstWidths.push_back(110); + lstCols.push_back(L"Min:"); + lstWidths.push_back(50); + lstCols.push_back(L"Max:"); + lstWidths.push_back(50); + lstCols.push_back(L"Avg:"); + lstWidths.push_back(50); + } void GetStrings(vector& lstStrings) const { TCHAR szTime[100]; @@ -189,11 +235,14 @@ class CExtendedLap private: ILapReceiver* m_pLapDB; CExtendedLap* m_pReferenceLap; - const ILap* m_pLap; +// const ILap* m_pLap; // Made public by KDJ SYSTEMTIME m_tmRecv; // when was this thing constructed? SYSTEMTIME m_tmStart; // when was this thing started on-track? public: + const ILap* m_pLap; vector m_lstPoints; // Made public by KDJ +// mutable map m_mapChannels; // we own these pointers. We get them allocated in ComputeLapData, and it is our responsibility to get them de-allocated + private: bool m_fComputeTimeSlip; // time-slip is the most expensive data channel, so let's allow the caller to choose not to compute it diff --git a/PitsideConsole/PitsideConsole/LapPainter.cpp b/PitsideConsole/PitsideConsole/LapPainter.cpp index 7fe0a06..ecd7ed8 100644 --- a/PitsideConsole/PitsideConsole/LapPainter.cpp +++ b/PitsideConsole/PitsideConsole/LapPainter.cpp @@ -1,4 +1,5 @@ -#include "stdafx.h" +#include "Stdafx.h" +#include "resource.h" #include "LapPainter.h" #include "LapData.h" #include "ArtUI.h" @@ -40,29 +41,30 @@ void CLapPainter::OGL_Paint() LAPDISPLAYSTYLE eDisplayStyle = m_pLapSupplier->GetLapDisplayStyle(m_iSupplierId); const LAPSUPPLIEROPTIONS& sfLapOpts = m_pLapSupplier->GetDisplayOptions(); +// vector lstLaps = GetLapsToShow(); + const CExtendedLap* pLap = NULL; switch(eDisplayStyle) { - case LAPDISPLAYSTYLE_MAP: - glViewport(0,0,RECT_WIDTH(&rcClient), RECT_HEIGHT(&rcClient)); - DrawLapLines(sfLapOpts); // Draws the lap as a map on primary display - break; - case LAPDISPLAYSTYLE_TRACTIONCIRCLE: - glViewport(0,0,RECT_WIDTH(&rcClient), RECT_HEIGHT(&rcClient)); - DrawTractionCircle(sfLapOpts, true); // Draw the traction circle graph if the window is active - break; - case LAPDISPLAYSTYLE_PLOT: - DrawGeneralGraph(sfLapOpts, true); // Draws the data graphs on the primary display - break; - case LAPDISPLAYSTYLE_RECEPTION: - DrawReceptionMap(sfLapOpts); // Draws the reception map on the primary display - break; - case LAPDISPLAYSTYLE_NOLAPS: - // user doesn't have any laps selected, so we should tell them to select some - DrawSelectLapsPrompt(); - break; + case LAPDISPLAYSTYLE_MAP: + glViewport(0,0,RECT_WIDTH(&rcClient), RECT_HEIGHT(&rcClient)); + DrawLapLines(sfLapOpts); // Draws the lap as a map on primary display + break; + case LAPDISPLAYSTYLE_TRACTIONCIRCLE: + glViewport(0,0,RECT_WIDTH(&rcClient), RECT_HEIGHT(&rcClient)); + DrawTractionCircle(sfLapOpts, true); // Draw the traction circle graph if the window is active + break; + case LAPDISPLAYSTYLE_PLOT: + DrawGeneralGraph(sfLapOpts, true); // Draws the data graphs on the primary display + break; + case LAPDISPLAYSTYLE_RECEPTION: + DrawReceptionMap(sfLapOpts); // Draws the reception map on the primary display + break; + case LAPDISPLAYSTYLE_NOLAPS: + // user doesn't have any laps selected, so we should tell them to select some + DrawSelectLapsPrompt(); + break; } - - SwapBuffers( OGL_GetDC() ); + SwapBuffers( OGL_GetDC() ); } void CLapPainter::DrawReceptionMap(const LAPSUPPLIEROPTIONS& sfLapOpts) const @@ -163,8 +165,9 @@ void CLapPainter::DrawSelectLapsPromptShort() const glScalef(1.0f, 0.90f, 1.0f); // Keep the same scaling - KDJ glOrtho(0, RECT_WIDTH(&rcClient),0, RECT_HEIGHT(&rcClient),-1.0,1.0); - DrawText(0.0, 70, "Click X-Accel"); - DrawText(0.0, 40, "to display"); + DrawText(0.0, 80, "Click "); + DrawText(0.0, 50, "X/Y/Z-Accel"); + DrawText(0.0, 20, "to display"); glPopMatrix(); } @@ -210,14 +213,7 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi DATA_CHANNEL eX; eX = DATA_CHANNEL_DISTANCE; -/* - static set i_Smoothed_LapId_X; // Tracker for which laps we have done smoothing on for X, Y, Z Acceleration data - i_Smoothed_LapId_X.begin(); - static set i_Smoothed_LapId_Y; // Tracker for which laps we have done smoothing on for X, Y, Z Acceleration data - i_Smoothed_LapId_Y.begin(); - static set i_Smoothed_LapId_Z; // Tracker for which laps we have done smoothing on for X, Y, Z Acceleration data - i_Smoothed_LapId_Z.begin(); -*/ + set setY; map mapMinY, mapMinYTemp; map mapMaxY, mapMaxYTemp; @@ -279,22 +275,22 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi break; } } - if(mapMinYTemp.find(eType) == mapMinYTemp.end()) + if(mapMinYTemp.find(eType) == mapMinYTemp.end()) { mapMinYTemp[eType] = min(pChannel->GetMin(),m_pLapSupplier->GetDataHardcodedMin(eType)); mapMaxYTemp[eType] = max(pChannel->GetMax(),m_pLapSupplier->GetDataHardcodedMax(eType)); } else - { - mapMinYTemp[eType] = min(pChannel->GetMin(),mapMinYTemp[eType]); - mapMaxYTemp[eType] = max(pChannel->GetMax(),mapMaxYTemp[eType]); + { + mapMinYTemp[eType] = min(pChannel->GetMin(),mapMinYTemp[eType]); // Make the minimum the least of the min of this lap, or the previous ones + mapMaxYTemp[eType] = max(pChannel->GetMax(),mapMaxYTemp[eType]); // Make the maximum the greater of the max of this lap, or the previous ones } //////////////////////////////// // Adding transformation functions here for Min/MaxY - if (b_TransformY == true && sfLapOpts.m_PlotPrefs[i_TransInt].fTransBValue < 0) + if (b_TransformY == true && (float)PolynomialFilter(mapMinYTemp[eType], sfLapOpts.m_PlotPrefs[i_TransInt].fTransAValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransBValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransCValue) > (float)PolynomialFilter(mapMaxYTemp[eType], sfLapOpts.m_PlotPrefs[i_TransInt].fTransAValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransBValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransCValue)) { - mapMaxY[eType] = (float)PolynomialFilter(mapMinYTemp[eType], sfLapOpts.m_PlotPrefs[i_TransInt].fTransAValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransBValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransCValue); mapMinY[eType] = (float)PolynomialFilter(mapMaxYTemp[eType], sfLapOpts.m_PlotPrefs[i_TransInt].fTransAValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransBValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransCValue); + mapMaxY[eType] = (float)PolynomialFilter(mapMinYTemp[eType], sfLapOpts.m_PlotPrefs[i_TransInt].fTransAValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransBValue, sfLapOpts.m_PlotPrefs[i_TransInt].fTransCValue); } else if (b_TransformY == true) { @@ -306,6 +302,7 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi mapMinY[eType] = mapMinYTemp[eType]; mapMaxY[eType] = mapMaxYTemp[eType]; } + //////////////////////////////// if (ValueDisplay == false) { @@ -395,23 +392,41 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi // Set up to perform the ZOOM function for DATA PLOT. static double dTranslateShiftX; static GLdouble dX,dY,dZ; - if (sfLapOpts.iZoomLevels != OldiZoomLevels) + CExtendedLap* pLap; + if (lstLaps.size() > 0) { - // The mouse is in our window, let's determine the closest X point to the mouse - gluUnProject(ptMouse.x, 0, 0, rgModelviewMatrix, rgProjMatrix, rgViewport, &dX, &dY, &dZ); - dTranslateShiftX = dX - dXShift; + pLap = lstLaps[lstLaps.size() - 1]; // Get the Reference Lap for scaling } else { - dTranslateShiftX = dX - dXShift; + return; } - OldiZoomLevels = sfLapOpts.iZoomLevels; + const IDataChannel* pDataX = pLap->GetChannel(m_pLapSupplier->GetXChannel()); // Get the list of X-Axis points for the Reference Lap + const vector &lstPointsX = pDataX->GetData(); + float dBestLength = -1; + DataPoint ptBest; // Best highlighted point where the mouse is on the Reference Lap + for(int x = 0; x< lstPointsX.size(); x++) + { + const DataPoint& p = lstPointsX[x]; + int iTime = m_pLapSupplier->GetLapHighlightTime(pLap); + if(abs(p.iTimeMs - iTime) < dBestLength || dBestLength < 0) + { + dBestLength = abs(p.iTimeMs - iTime); + ptBest = p; // ptBest contains the X/Y values for the highlighted point of the Reference Lap + } + } + + if(dScaleAmt > 1) + { + dTranslateShiftX = ptBest.flValue - dXShift; // Calculate the shift amount for the highlighted point in the Reference Lap if we are zoomed in + } + OldiZoomLevels = sfLapOpts.iZoomLevels; // Save the zoom level glTranslated(dTranslateShiftX, 0, 0); // Translate the map to origin on x-axis only - glScaled(dScaleAmt, 1.0, 1.0); // No scaling of Y-axis on Data Plot. + glScaled(dScaleAmt, 1.0, 1.0); // No scaling of Y-axis on Data Plot, only scale the X-axis. glTranslated(-dTranslateShiftX, 0, 0); // Now put the map back in its place // Panning functionality - glTranslated(dXShift - dMinX, 0, 0); // Offset for this is still slight wrong, but the best for now. + glTranslated(dXShift - dMinX, 0, 0); // Shift the graph based upon the mouse movement // Now having shifted, let's get our new model matrices glGetDoublev(GL_MODELVIEW_MATRIX, rgModelviewMatrix); @@ -427,7 +442,15 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi { if (sfLapOpts.m_SplitPoints[z].m_sfXPoint != 0.0f) { - CExtendedLap* pLap = lstLaps[lstLaps.size() - 1]; // Last lap is the Reference Lap + CExtendedLap* pLap; + if (lstLaps.size() > 0) + { + pLap = lstLaps[lstLaps.size() - 1]; // Get the Reference Lap for scaling + } + else + { + return; + } const IDataChannel* pDistance = pLap->GetChannel(DATA_CHANNEL_DISTANCE); const double dDistance = pDistance->GetValue(sfLapOpts.m_SplitPoints[z].m_sfSectorTime) - pDistance->GetValue(sfLapOpts.m_SplitPoints[0].m_sfSectorTime); double flLine = dDistance; @@ -478,14 +501,14 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi CExtendedLap* pLap = lstLaps[x]; const IDataChannel* pDataX = pLap->GetChannel(m_pLapSupplier->GetXChannel()); const IDataChannel* pDataY = pLap->GetChannel(*i); -/* // If Traction Circle window is active, pull and smooth that data + // If we are dealing with accelerometer data, pull and smooth that data IDataChannel* pDataX_ACCEL; IDataChannel* pDataY_ACCEL; IDataChannel* pDataZ_ACCEL; pDataX_ACCEL = (IDataChannel*) pLap->GetChannel(DATA_CHANNEL_X_ACCEL); pDataY_ACCEL = (IDataChannel*) pLap->GetChannel(DATA_CHANNEL_Y_ACCEL); pDataZ_ACCEL = (IDataChannel*) pLap->GetChannel(DATA_CHANNEL_Z_ACCEL); -*/ + float r; float g; float b; @@ -503,170 +526,111 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi if(pDataX && pDataY) { // tracking what we want to highlight -// static bool bSmoothFlagX, bSmoothFlagY, bSmoothFlagZ; // Flag for checking if smooth has been done or not. False = smoothing not yet done + int w = 4; // * Default setting. w is the size of the smoothing window, taken on each side of sample float dBestLength = -1; float dTimeToHighlight = -1; - const vector &lstPointsX = (vector&) pDataX->GetData(); - const vector &lstPointsY = (vector&) pDataY->GetData(); -/* // Changed to non-constant as we want to smooth the data sometimes +// const vector &lstPointsX = (vector&) pDataX->GetData(); +// const vector &lstPointsY = (vector&) pDataY->GetData(); + // Changed to non-constant as we want to smooth the data sometimes vector &lstPointsX = (vector&) pDataX->GetData(); vector &lstPointsY = (vector&) pDataY->GetData(); vector lstPointsX_Accel; - vector &p_lstPointsX_Accel = (vector&) lstPointsX_Accel; + lstPointsX_Accel.begin(); vector lstPointsY_Accel; - vector &p_lstPointsY_Accel = (vector&) lstPointsY_Accel; + lstPointsY_Accel.begin(); vector lstPointsZ_Accel; - vector &p_lstPointsZ_Accel = (vector&) lstPointsZ_Accel; - for(set::iterator q = setY.begin(); q != setY.end(); q++) + lstPointsZ_Accel.begin(); + if ( eX == DATA_CHANNEL_X_ACCEL && sfLapOpts.bSmoothYesNo == true ) { - if ( *q == DATA_CHANNEL_X_ACCEL && bSmoothFlagX == false ) - { - lstPointsX_Accel.clear(); - lstPointsX_Accel = pDataX_ACCEL->GetData(); // pDataY->GetData() - } - if ( *q == DATA_CHANNEL_Y_ACCEL && bSmoothFlagY == false ) - { - lstPointsY_Accel.clear(); - lstPointsY_Accel = pDataY_ACCEL->GetData(); // pDataY->GetData() - } - if ( *q == DATA_CHANNEL_Z_ACCEL && bSmoothFlagZ == false ) - { - lstPointsZ_Accel.clear(); - lstPointsZ_Accel = pDataZ_ACCEL->GetData(); // pDataY->GetData() - } + lstPointsX_Accel.clear(); + lstPointsX_Accel = pDataX_ACCEL->GetData(); // pDataY->GetData() + w = lstPointsX_Accel.size() / 400; // Sets the BoxAverage smoothing width, based upon the number of data points } - int w = 8; // * w is the size of the smoothing window, taken on each side of sample - // If Accel X or Traction Circle are to be displayed, smooth the Accelerometer data - if ( m_pLapSupplier->GetXChannel() == DATA_CHANNEL_X_ACCEL || *i == DATA_CHANNEL_X_ACCEL || sfLapOpts.bTractionCircle ) + if ( eX == DATA_CHANNEL_Y_ACCEL && sfLapOpts.bSmoothYesNo == true ) { - // Smooth the data if the X-axis is displaying ACCEL type data - if ( i_Smoothed_LapId_X.size() ) - { - bSmoothFlagX = false; // Assume that we need to smooth the Accel data, then check if this lap has already been smoothed - for(set::iterator t = i_Smoothed_LapId_X.begin(); t != i_Smoothed_LapId_X.end(); t++) - { - if ( pLap->GetLap()->GetLapId() == *t ) // Lap has already been marked as smoothed, so abort - { - bSmoothFlagX = true; // Otherwise smooth the Accel data - break; - } - } - } + lstPointsY_Accel.clear(); + lstPointsY_Accel = pDataY_ACCEL->GetData(); // pDataY->GetData() + w = lstPointsY_Accel.size() / 400; // Sets the BoxAverage smoothing width, based upon the number of data points } - - // If Accel Y or Traction Circle are to be displayed, smooth the Accelerometer data - if ( m_pLapSupplier->GetXChannel() == DATA_CHANNEL_Y_ACCEL || *i == DATA_CHANNEL_Y_ACCEL || sfLapOpts.bTractionCircle ) + if ( eX == DATA_CHANNEL_Z_ACCEL && sfLapOpts.bSmoothYesNo == true ) { - // Smooth the data if the X-axis is displaying ACCEL type data - if ( i_Smoothed_LapId_X.size() ) - { - bSmoothFlagY = false; // Assume that we need to smooth the Accel data, then check if this lap has already been smoothed - for(set::iterator t = i_Smoothed_LapId_Y.begin(); t != i_Smoothed_LapId_Y.end(); t++) - { - if ( pLap->GetLap()->GetLapId() == *t ) // Lap has already been marked as smoothed, so abort - { - bSmoothFlagY = true; // Otherwise smooth the Accel data - break; - } - } - } + lstPointsZ_Accel.clear(); + lstPointsZ_Accel = pDataZ_ACCEL->GetData(); // pDataY->GetData() + w = lstPointsZ_Accel.size() / 400; // Sets the BoxAverage smoothing width, based upon the number of data points } - // If Accel Z is to be displayed, smooth the Accelerometer data - if ( m_pLapSupplier->GetXChannel() == DATA_CHANNEL_Z_ACCEL || *i == DATA_CHANNEL_Z_ACCEL ) + if ( pDataY->GetChannelType() == DATA_CHANNEL_X_ACCEL && sfLapOpts.bSmoothYesNo == true ) { - // Smooth the data if the X-axis is displaying ACCEL type data - if ( i_Smoothed_LapId_Z.size() ) - { - bSmoothFlagZ = false; // Assume that we need to smooth the Accel data, then check if this lap has already been smoothed - for(set::iterator t = i_Smoothed_LapId_Z.begin(); t != i_Smoothed_LapId_Z.end(); t++) - { - if ( pLap->GetLap()->GetLapId() == *t ) // Lap has already been marked as smoothed, so abort - { - bSmoothFlagZ = true; // Otherwise smooth the Accel data - break; - } - } - } + lstPointsX_Accel.clear(); + lstPointsX_Accel = pDataX_ACCEL->GetData(); // pDataY->GetData() + w = lstPointsX_Accel.size() / 400; // Sets the BoxAverage smoothing width, based upon the number of data points + } + if ( pDataY->GetChannelType() == DATA_CHANNEL_Y_ACCEL && sfLapOpts.bSmoothYesNo == true ) + { + lstPointsY_Accel.clear(); + lstPointsY_Accel = pDataY_ACCEL->GetData(); // pDataY->GetData() + w = lstPointsY_Accel.size() / 400; // Sets the BoxAverage smoothing width, based upon the number of data points + } + if ( pDataY->GetChannelType() == DATA_CHANNEL_Z_ACCEL && sfLapOpts.bSmoothYesNo == true ) + { + lstPointsZ_Accel.clear(); + lstPointsZ_Accel = pDataZ_ACCEL->GetData(); // pDataY->GetData() + w = lstPointsZ_Accel.size() / 400; // Sets the BoxAverage smoothing width, based upon the number of data points } vector& lstSmoothPts = (vector) pDataX->GetData(); - if( (eX == DATA_CHANNEL_X_ACCEL || eX == DATA_CHANNEL_Y_ACCEL || eX == DATA_CHANNEL_Z_ACCEL) || sfLapOpts.bTractionCircle ) + if( (eX == DATA_CHANNEL_X_ACCEL || eX == DATA_CHANNEL_Y_ACCEL || eX == DATA_CHANNEL_Z_ACCEL) && sfLapOpts.bSmoothYesNo == true ) { // Smooth out the accerlometer data for all axes before displaying them on the X/Y-axes or in the Traction Circle display if (lstPointsX_Accel.size() ) { lstSmoothPts.clear(); - lstSmoothPts = (vector) pDataX_ACCEL->GetData(); - fBoxMovingAvg( lstPointsX_Accel.size(), lstPointsX_Accel, w, lstSmoothPts, bSmoothFlagX ); -// lstPointsX_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set - lstPointsX = lstSmoothPts; // Copy the smoothed data points over to the original data set + fBoxMovingAvg( lstPointsX_Accel.size(), lstPointsX_Accel, w, lstSmoothPts, false ); + lstPointsX_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set lstSmoothPts.clear(); - bSmoothFlagX = true; // Set switch so that no more smoothing is done - i_Smoothed_LapId_X.insert( pLap->GetLap()->GetLapId() ); // Add the name of this lap to the set of smoothed laps } if (lstPointsY_Accel.size() ) { lstSmoothPts.clear(); - lstSmoothPts = (vector) pDataY_ACCEL->GetData(); // Now do the same for the Y_ACCEL data - fBoxMovingAvg( lstPointsY_Accel.size(), lstPointsY_Accel, w, lstSmoothPts, bSmoothFlagY ); -// lstPointsY_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set - lstPointsX = lstSmoothPts; // Copy the smoothed data points over to the original data set + fBoxMovingAvg( lstPointsY_Accel.size(), lstPointsY_Accel, w, lstSmoothPts, false ); + lstPointsY_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set lstSmoothPts.clear(); - bSmoothFlagY = true; // Set switch so that no more smoothing is done - i_Smoothed_LapId_Y.insert( pLap->GetLap()->GetLapId() ); // Add the name of this lap to the set of smoothed laps } if (lstPointsZ_Accel.size() ) { lstSmoothPts.clear(); - lstSmoothPts = (vector) pDataZ_ACCEL->GetData(); // Now do the same for the Z_ACCEL data - fBoxMovingAvg( lstPointsZ_Accel.size(), lstPointsZ_Accel, w, lstSmoothPts, bSmoothFlagZ ); -// lstPointsZ_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set - lstPointsX = lstSmoothPts; // Copy the smoothed data points over to the original data set + fBoxMovingAvg( lstPointsZ_Accel.size(), lstPointsZ_Accel, w, lstSmoothPts, false ); + lstPointsZ_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set lstSmoothPts.clear(); - bSmoothFlagZ = true; // Set switch so that no more smoothing is done - i_Smoothed_LapId_Z.insert( pLap->GetLap()->GetLapId() ); // Add the name of this lap to the set of smoothed laps } - } + } - if( (*i == DATA_CHANNEL_X_ACCEL || *i == DATA_CHANNEL_Y_ACCEL || *i == DATA_CHANNEL_Z_ACCEL) || sfLapOpts.bTractionCircle ) + if( (*i == DATA_CHANNEL_X_ACCEL || *i == DATA_CHANNEL_Y_ACCEL || *i == DATA_CHANNEL_Z_ACCEL) && sfLapOpts.bSmoothYesNo == true ) { // Smooth out the accerlometer data for all axes before displaying them on the X/Y-axes or in the Traction Circle display if (lstPointsX_Accel.size() ) { lstSmoothPts.clear(); - lstSmoothPts = (vector) pDataX_ACCEL->GetData(); - fBoxMovingAvg( lstPointsX_Accel.size(), lstPointsX_Accel, w, lstSmoothPts, bSmoothFlagX ); -// lstPointsX_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set - lstPointsY = lstSmoothPts; // Copy the smoothed data points over to the original data set + fBoxMovingAvg( lstPointsX_Accel.size(), lstPointsX_Accel, w, lstSmoothPts, false ); + lstPointsX_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set lstSmoothPts.clear(); - bSmoothFlagX = true; // Set switch so that no more smoothing is done - i_Smoothed_LapId_X.insert( pLap->GetLap()->GetLapId() ); // Add the name of this lap to the set of smoothed laps } if (lstPointsY_Accel.size() ) { lstSmoothPts.clear(); - lstSmoothPts = (vector) pDataY_ACCEL->GetData(); // Now do the same for the Y_ACCEL data - fBoxMovingAvg( lstPointsY_Accel.size(), lstPointsY_Accel, w, lstSmoothPts, bSmoothFlagY ); -// lstPointsY_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set - lstPointsY = lstSmoothPts; // Copy the smoothed data points over to the original data set + fBoxMovingAvg( lstPointsY_Accel.size(), lstPointsY_Accel, w, lstSmoothPts, false ); + lstPointsY_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set lstSmoothPts.clear(); - bSmoothFlagY = true; // Set switch so that no more smoothing is done - i_Smoothed_LapId_Y.insert( pLap->GetLap()->GetLapId() ); // Add the name of this lap to the set of smoothed laps } if (lstPointsZ_Accel.size() ) { lstSmoothPts.clear(); - lstSmoothPts = (vector) pDataZ_ACCEL->GetData(); // Now do the same for the Z_ACCEL data - fBoxMovingAvg( lstPointsZ_Accel.size(), lstPointsZ_Accel, w, lstSmoothPts, bSmoothFlagZ ); -// lstPointsZ_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set - lstPointsY = lstSmoothPts; // Copy the smoothed data points over to the original data set + fBoxMovingAvg( lstPointsZ_Accel.size(), lstPointsZ_Accel, w, lstSmoothPts, false ); + lstPointsZ_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set lstSmoothPts.clear(); - bSmoothFlagZ = true; // Set switch so that no more smoothing is done - i_Smoothed_LapId_Z.insert( pLap->GetLap()->GetLapId() ); // Add the name of this lap to the set of smoothed laps } - } -*/ + } + glEnable(GL_LINE_STIPPLE); glLineStipple(factor, pattern); // Set the line dash/dot characteristics if(sfLapOpts.fDrawLines == false) @@ -686,10 +650,46 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi glBegin(GL_LINE_STRIP); } - vector::const_iterator iX = lstPointsX.begin(); - vector::const_iterator iXend = lstPointsX.end(); - vector::const_iterator iY = lstPointsY.begin(); - vector::const_iterator iYend = lstPointsY.end(); + vector::const_iterator iX ; + if ( eX == DATA_CHANNEL_X_ACCEL && lstPointsX_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iX = lstPointsX_Accel.begin(); + else if ( eX == DATA_CHANNEL_Y_ACCEL && lstPointsY_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iX = lstPointsY_Accel.begin(); + else if ( eX == DATA_CHANNEL_Z_ACCEL && lstPointsZ_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iX = lstPointsZ_Accel.begin(); + else + iX = lstPointsX.begin(); + + vector::const_iterator iXend; + if ( eX == DATA_CHANNEL_X_ACCEL && lstPointsX_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iXend = lstPointsX_Accel.end(); + else if ( eX == DATA_CHANNEL_Y_ACCEL && lstPointsY_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iXend = lstPointsY_Accel.end(); + else if ( eX == DATA_CHANNEL_Z_ACCEL && lstPointsZ_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iXend = lstPointsZ_Accel.end(); + else + iXend = lstPointsX.end(); + + vector::const_iterator iY; + if ( *i == DATA_CHANNEL_X_ACCEL && lstPointsX_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iY = lstPointsX_Accel.begin(); + else if ( *i == DATA_CHANNEL_Y_ACCEL && lstPointsY_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iY = lstPointsY_Accel.begin(); + else if ( *i == DATA_CHANNEL_Z_ACCEL && lstPointsZ_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iY = lstPointsZ_Accel.begin(); + else + iY = lstPointsY.begin(); + + vector::const_iterator iYend; + if ( *i == DATA_CHANNEL_X_ACCEL && lstPointsX_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iYend = lstPointsX_Accel.end(); + else if ( *i == DATA_CHANNEL_Y_ACCEL && lstPointsY_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iYend = lstPointsY_Accel.end(); + else if ( *i == DATA_CHANNEL_Z_ACCEL && lstPointsZ_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iYend = lstPointsZ_Accel.end(); + else + iYend = lstPointsY.end(); + while(iX != iXend && iY != iYend) { float dX; @@ -700,14 +700,97 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi if(ptX.iTimeMs < ptY.iTimeMs) { iTimeUsed = ptX.iTimeMs; - dX = ptX.flValue; - dY = pDataY->GetValue(ptX.iTimeMs, iY); + if ( *i == DATA_CHANNEL_X_ACCEL && lstPointsX_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + { + for(vector::iterator t = lstPointsX_Accel.begin(); t != lstPointsX_Accel.end(); t++) + { + DataPoint& ptTemp = *t; + if ( ptTemp.iTimeMs >= ptX.iTimeMs ) // Found smoothed point, let's load the Y value + { + dY = ptTemp.flValue; + break; + } + } + } + + else if ( *i == DATA_CHANNEL_Y_ACCEL && lstPointsY_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + { + for(vector::iterator t = lstPointsY_Accel.begin(); t != lstPointsY_Accel.end(); t++) + { + DataPoint& ptTemp = *t; + if ( ptTemp.iTimeMs >= ptX.iTimeMs ) // Found smoothed point, let's load the Y value + { + dY = ptTemp.flValue; + break; + } + } + } + + else if ( *i == DATA_CHANNEL_Z_ACCEL && lstPointsZ_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + { + for(vector::iterator t = lstPointsY_Accel.begin(); t != lstPointsY_Accel.end(); t++) + { + DataPoint& ptTemp = *t; + if ( ptTemp.iTimeMs >= ptX.iTimeMs ) // Found smoothed point, let's load the Y value + { + dY = ptTemp.flValue; + break; + } + } + } + else + { + dX = ptX.flValue; + } + dY = pDataY->GetValue(ptX.iTimeMs, iY); iX++; } else if(ptX.iTimeMs > ptY.iTimeMs) { iTimeUsed = ptY.iTimeMs; - dX = pDataX->GetValue(ptY.iTimeMs, iX); + + if ( eX == DATA_CHANNEL_X_ACCEL && lstPointsX_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + { + for(vector::iterator t = lstPointsX_Accel.begin(); t != lstPointsX_Accel.end(); t++) + { + DataPoint& ptTemp = *t; + if ( ptTemp.iTimeMs >= ptX.iTimeMs ) // Found smoothed point, let's load the Y value + { + dX = ptTemp.flValue; + break; + } + } + } + + else if ( eX == DATA_CHANNEL_Y_ACCEL && lstPointsY_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + { + for(vector::iterator t = lstPointsY_Accel.begin(); t != lstPointsY_Accel.end(); t++) + { + DataPoint& ptTemp = *t; + if ( ptTemp.iTimeMs >= ptX.iTimeMs ) // Found smoothed point, let's load the Y value + { + dX = ptTemp.flValue; + break; + } + } + } + + else if ( eX == DATA_CHANNEL_Z_ACCEL && lstPointsZ_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + { + for(vector::iterator t = lstPointsY_Accel.begin(); t != lstPointsY_Accel.end(); t++) + { + DataPoint& ptTemp = *t; + if ( ptTemp.iTimeMs >= ptX.iTimeMs ) // Found smoothed point, let's load the Y value + { + dX = ptTemp.flValue; + break; + } + } + } + else + { + dX = pDataX->GetValue(ptY.iTimeMs, iX); + } dY = ptY.flValue; iY++; } @@ -724,12 +807,13 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi // Can add transformation function here for Y if (sfLapOpts.m_PlotPrefs[y].iTransformYesNo == true) { - dY = PolynomialFilter(ptY.flValue, sfLapOpts.m_PlotPrefs[y].fTransAValue, sfLapOpts.m_PlotPrefs[y].fTransBValue, sfLapOpts.m_PlotPrefs[y].fTransCValue); +// dY = PolynomialFilter(ptY.flValue, sfLapOpts.m_PlotPrefs[y].fTransAValue, sfLapOpts.m_PlotPrefs[y].fTransBValue, sfLapOpts.m_PlotPrefs[y].fTransCValue); + dY = PolynomialFilter(dY, sfLapOpts.m_PlotPrefs[y].fTransAValue, sfLapOpts.m_PlotPrefs[y].fTransBValue, sfLapOpts.m_PlotPrefs[y].fTransCValue); } - else - { - dY = ptY.flValue; - } +// else +// { +// dY = ptY.flValue; +// } ////////////////////////////////////////// glVertex2f(dX,dY); @@ -767,16 +851,15 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi glPushMatrix(); // <-- pushes a matrix onto the opengl matrix stack. glLoadIdentity(); // <-- makes it so that the matrix stack just converts all our coordinates directly to window coordinates glOrtho(0, RECT_WIDTH(&rcSpot),0, RECT_HEIGHT(&rcSpot),-1.0,1.0); - /* <-- tells OpenGL that it should show us the part of the openGL "world" that corresponds to - (0...window width, 0 ... window height). This completes the "hey opengl, just draw where we - tell you to plz" part of the function */ - + // <-- tells OpenGL that it should show us the part of the openGL "world" that corresponds to (0...window width, 0 ... window height). + // This completes the "hey opengl, just draw where we tell you to plz" part of the function for(int x = 0; x < lstMousePointsToDraw.size(); x++) // <-- loops through all the stupid boxes/lines we want to draw { const CExtendedLap* pLap = lstMousePointsToDraw[x].m_pLap; // <-- gets the lap data we want to draw const POINT& ptWindow = lstMousePointsToDraw[x].m_ptWindow; // <-- gets info about where in the window we want to draw the box const IDataChannel* pDataX = lstMousePointsToDraw[x].m_pDataX; // <-- gets the x channel data const IDataChannel* pDataY = lstMousePointsToDraw[x].m_pDataY; // <-- gets the y channel data + POINT Temp_ptWindow; // Point for transforming Y values in highlight loop float r; float g; @@ -806,10 +889,15 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi if (sfLapOpts.m_PlotPrefs[y].iTransformYesNo == true) { TempY = PolynomialFilter(pDataY->GetValue(dTimeToHighlight), sfLapOpts.m_PlotPrefs[y].fTransAValue, sfLapOpts.m_PlotPrefs[y].fTransBValue, sfLapOpts.m_PlotPrefs[y].fTransCValue); + // Transform highlight points into OpenGL space + GLdouble winx,winy,winz; + gluProject(0, (GLdouble)TempY, 0, rgModelviewMatrix, rgProjMatrix, rgViewport, &winx, &winy, &winz); + Temp_ptWindow.y = (int)winy; } else { TempY = pDataY->GetValue(dTimeToHighlight); + Temp_ptWindow.y = ptWindow.y; } ////////////////////////////////////////// GetChannelString(lstMousePointsToDraw[x].m_eChannelY, sfLapOpts.eUnitPreference, TempY, szYString, NUMCHARS(szYString)); @@ -826,17 +914,18 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi DrawText(100.0,(x+2)*GetWindowFontSize(),szText); // <-- draws the text from the bottom of the window, working upwards // we also want to draw a highlighted square - DrawGLFilledSquare(ptWindow.x, ptWindow.y, 3); // <-- draws the stupid little box at ptWindow.x. +// DrawGLFilledSquare(ptWindow.x, ptWindow.y, 3); // <-- draws the stupid little box at ptWindow.x. + DrawGLFilledSquare((double)ptWindow.x, (double)(Temp_ptWindow.y - rcSpot.top), 3); // <-- draws the stupid little box at ptWindow.x. // we also want to draw a highlighted LINE for that individual lap/graph combination - glLineWidth(1); // Added by KDJ. Skinny line for Distance markers. - glBegin(GL_LINE_STRIP); // Added by KDJ - glVertex3f(ptWindow.x, 0, 0); // Added by KDJ, modified by Chas - glVertex3f(ptWindow.x,rcSpot.bottom,0); // Added by KDJ - glEnd(); // Added by KDJ + glLineWidth(1); // Skinny vertical line for mouse location markers. + glBegin(GL_LINE_STRIP); + glVertex3f(ptWindow.x, 0, 0); + glVertex3f(ptWindow.x,rcSpot.bottom,0); + glEnd(); } } glPopMatrix(); - glPopMatrix(); // Should there be two of these here? + glPopMatrix(); // Pops us out of windows space to OGL space } rcSpot.top += iSegmentHeight; rcSpot.bottom += iSegmentHeight; @@ -845,13 +934,40 @@ void CLapPainter::DrawGeneralGraph(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHi } - void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHighlightXAxis) { vector lstLaps = m_pLapSupplier->GetLapsToShow(); - + // Let's check on which orientation the phone is in so that the Traction Circle is displayed correctly + // Vertical/Landscape: X = X-Accel, Y=Y-Accel; Vertical/Portrait: X = Z-Accel, Y=Y-Accel; Flat/Landscape: X=X-Accel, Y=Z-Accel; Flat/Portrait: X=Z-Axis, Y=X-Axis DATA_CHANNEL eX; - eX = DATA_CHANNEL_X_ACCEL; + DATA_CHANNEL DataY; + switch (sfLapOpts.e_Orientation) + { + case VERTICAL_LANDSCAPE: + { + eX = DATA_CHANNEL_X_ACCEL; + DataY = DATA_CHANNEL_Y_ACCEL; + break; + } + case VERTICAL_PORTRAIT: + { + eX = DATA_CHANNEL_Z_ACCEL; + DataY = DATA_CHANNEL_Y_ACCEL; + break; + } + case FLAT_LANDSCAPE: + { + eX = DATA_CHANNEL_X_ACCEL; + DataY = DATA_CHANNEL_Z_ACCEL; + break; + } + case FLAT_PORTRAIT: + { + eX = DATA_CHANNEL_Z_ACCEL; + DataY = DATA_CHANNEL_X_ACCEL; + break; + } + } set setY; map mapMinY, mapMinYTemp; map mapMaxY, mapMaxYTemp; @@ -871,8 +987,6 @@ void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool f DATA_CHANNEL eDataX = eX; const IDataChannel* pDataX = pLap->GetChannel(eDataX); if(!pDataX || !pDataX->IsValid() || pDataX->GetData().size() <= 0) continue; - - DATA_CHANNEL DataY = DATA_CHANNEL_Y_ACCEL; { ////////////////////////////////// b_TransformY = false; @@ -972,7 +1086,7 @@ void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool f // now we have the bounds of all the laps we've looked at, so let's draw them glPushMatrix(); glLoadIdentity(); - glScalef(1.0f, 0.90f, 1.0f); // Let's scale it so that graphs don't touch each other. + glScalef(1.0f, 1.0f, 1.0f); // Let's scale it so that graphs don't touch each other. glOrtho(dMinX, dMaxX, mapMinY[*i], mapMaxY[*i], -1.0, 1.0); // Set up the non-zoomed/panned view for the map @@ -999,14 +1113,6 @@ void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool f } Vector2D ptHighlight; // the (x,y) coords in unit-space that we want to highlight. Example: for a speed-distance graph, x would be in distance units, y in velocities. - POINT ptMouse; - if(GetMouse(&ptMouse) && m_pLapSupplier->IsHighlightSource(m_iSupplierId)) - { - // The mouse is in our window... we make our own highlighter, ignoring anything that got sent to us - GLdouble dX,dY,dZ; - gluUnProject(ptMouse.x, ptMouse.y, 0, rgModelviewMatrix, rgProjMatrix, rgViewport, &dX, &dY, &dZ); - ptHighlight = V2D(dX,0); - } for(int x = 0; x < lstLaps.size(); x++) { CExtendedLap* pLap = lstLaps[x]; @@ -1016,11 +1122,19 @@ void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool f if(pDataX && pDataY) { // tracking what we want to highlight + int w = 4; // * Default setting. w is the size of the smoothing window, taken on each side of sample float dBestLength = -1; float dTimeToHighlight = -1; // Changed to non-constant as we want to smooth the data sometimes vector& lstPointsX = (vector&) pDataX->GetData(); vector& lstPointsY = (vector&) pDataY->GetData(); + // If we are dealing with accelerometer data, pull and smooth that data + IDataChannel* pDataX_ACCEL; + IDataChannel* pDataY_ACCEL; + IDataChannel* pDataZ_ACCEL; + pDataX_ACCEL = (IDataChannel*) pLap->GetChannel(DATA_CHANNEL_X_ACCEL); + pDataY_ACCEL = (IDataChannel*) pLap->GetChannel(DATA_CHANNEL_Y_ACCEL); + pDataZ_ACCEL = (IDataChannel*) pLap->GetChannel(DATA_CHANNEL_Z_ACCEL); float r; float g; @@ -1037,10 +1151,65 @@ void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool f glPointSize(2.0f); glBegin(GL_POINTS); - vector::const_iterator iX = lstPointsX.begin(); - vector::const_iterator iXend = lstPointsX.end(); - vector::const_iterator iY = lstPointsY.begin(); - vector::const_iterator iYend = lstPointsY.end(); + vector lstPointsX_Accel; + lstPointsX_Accel.begin(); + vector lstPointsY_Accel; + lstPointsY_Accel.begin(); + vector lstPointsZ_Accel; + lstPointsZ_Accel.begin(); + if ( eX == DATA_CHANNEL_X_ACCEL && sfLapOpts.bSmoothYesNo == true ) + { + lstPointsX_Accel.clear(); + lstPointsX_Accel = pDataX_ACCEL->GetData(); // pDataY->GetData() + w = lstPointsX_Accel.size() / 400; // Sets the BoxAverage smoothing width, based upon the number of data points + } + if ( pDataY->GetChannelType() == DATA_CHANNEL_Y_ACCEL && sfLapOpts.bSmoothYesNo == true ) + { + lstPointsY_Accel.clear(); + lstPointsY_Accel = pDataY_ACCEL->GetData(); // pDataY->GetData() + w = lstPointsY_Accel.size() / 400; // Sets the BoxAverage smoothing width, based upon the number of data points + } + vector& lstSmoothPts = (vector) pDataX->GetData(); + // Smooth out the accerlometer data for X-Axis before displaying them on the Traction Circle display + if (lstPointsX_Accel.size() ) + { + lstSmoothPts.clear(); + fBoxMovingAvg( lstPointsX_Accel.size(), lstPointsX_Accel, w, lstSmoothPts, false ); + lstPointsX_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set + lstSmoothPts.clear(); + } + if (lstPointsY_Accel.size() ) + { + lstSmoothPts.clear(); + fBoxMovingAvg( lstPointsY_Accel.size(), lstPointsY_Accel, w, lstSmoothPts, false ); + lstPointsY_Accel = lstSmoothPts; // Copy the smoothed data points over to the original data set + lstSmoothPts.clear(); + } + vector::const_iterator iX ; + if ( eX == DATA_CHANNEL_X_ACCEL && lstPointsX_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iX = lstPointsX_Accel.begin(); + else + iX = lstPointsX.begin(); + + vector::const_iterator iXend; + if ( eX == DATA_CHANNEL_X_ACCEL && lstPointsX_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iXend = lstPointsX_Accel.end(); + else + iXend = lstPointsX.end(); + + vector::const_iterator iY; + if ( *i == DATA_CHANNEL_Y_ACCEL && lstPointsY_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iY = lstPointsY_Accel.begin(); + else + iY = lstPointsY.begin(); + + vector::const_iterator iYend; + if ( *i == DATA_CHANNEL_Y_ACCEL && lstPointsY_Accel.size() && sfLapOpts.bSmoothYesNo == true ) + iYend = lstPointsY_Accel.end(); + else + iYend = lstPointsY.end(); + + dTimeToHighlight = m_pLapSupplier->GetLapHighlightTime(pLap); while(iX != iXend && iY != iYend) { float dX; @@ -1075,31 +1244,24 @@ void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool f // Can add transformation function here for Y if (sfLapOpts.m_PlotPrefs[y].iTransformYesNo == true) { - dY = PolynomialFilter(ptY.flValue, sfLapOpts.m_PlotPrefs[y].fTransAValue, sfLapOpts.m_PlotPrefs[y].fTransBValue, sfLapOpts.m_PlotPrefs[y].fTransCValue); + dY = PolynomialFilter(dY, sfLapOpts.m_PlotPrefs[y].fTransAValue, sfLapOpts.m_PlotPrefs[y].fTransBValue, sfLapOpts.m_PlotPrefs[y].fTransCValue); } - else - { - dY = ptY.flValue; - } ////////////////////////////////////////// - glVertex2f(dX,dY); - - // if we're a highlight source, try to figure out the closest point for this lap - if(m_pLapSupplier->IsHighlightSource(m_iSupplierId)) - { - Vector2D vPt = V2D(dX,0); - Vector2D vDiff = vPt - ptHighlight; - if(vDiff.Length() < dBestLength || dBestLength < 0) - { - dBestLength = vDiff.Length(); - dTimeToHighlight = iTimeUsed; - } - } + if (sfLapOpts.bTractionCircle) // User wants dynamic traction circle, not full lap to be displayed + { + if (iTimeUsed > (dTimeToHighlight - 1500) && iTimeUsed <= (dTimeToHighlight)) // Only display traction circle points near the highlighted point + { + glVertex2f(dX,dY); + } + } + else + { + glVertex2f(dX,dY); + } } glEnd(); // for each lap, draw an indicator of the closest thing to the mouse // if we're not a source, use the given time to highlight - dTimeToHighlight = m_pLapSupplier->GetLapHighlightTime(pLap); UpdateHighlightPointList(lstMousePointsToDraw, pLap, rgModelviewMatrix, rgProjMatrix, rgViewport, dTimeToHighlight, pDataX, pDataY); } } // end lap loop @@ -1109,9 +1271,9 @@ void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool f glPushMatrix(); // <-- pushes a matrix onto the opengl matrix stack. glLoadIdentity(); // <-- makes it so that the matrix stack just converts all our coordinates directly to window coordinates glOrtho(0, RECT_WIDTH(&rcSpot),0, RECT_HEIGHT(&rcSpot),-1.0,1.0); - /* <-- tells OpenGL that it should show us the part of the openGL "world" that corresponds to - (0...window width, 0 ... window height). This completes the "hey opengl, just draw where we - tell you to plz" part of the function */ +// <-- tells OpenGL that it should show us the part of the openGL "world" that corresponds to +// (0...window width, 0 ... window height). This completes the "hey opengl, just draw where we +// tell you to plz" part of the function for(int x = 0; x < lstMousePointsToDraw.size(); x++) // <-- loops through all the stupid boxes/lines we want to draw { @@ -1142,62 +1304,6 @@ void CLapPainter::DrawTractionCircle(const LAPSUPPLIEROPTIONS& sfLapOpts, bool f } // end y-channel data channel loop } - - - - -/* -void CLapPainter::MagicDeterminingFunction(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHighlightXAxis) -{ - for(int x = 0; x < lstMousePointsToDraw.size(); x++) // <-- loops through all the stupid boxes/lines we want to draw - { - const CExtendedLap* pLap = lstMousePointsToDraw[x].m_pLap; // <-- gets the lap data we want to draw - const POINT& ptWindow = lstMousePointsToDraw[x].m_ptWindow; // <-- gets info about where in the window we want to draw the box - const IDataChannel* pDataX = lstMousePointsToDraw[x].m_pDataX; // <-- gets the x channel data - const IDataChannel* pDataY = lstMousePointsToDraw[x].m_pDataY; // <-- gets the y channel data - - float r; - float g; - float b; - MakeColor ( pLap, x == (lstLaps.size() - 1), &r, &g, &b ); // Function picks color to use and tells opengl to draw the following in the colour we just made up - - // if we're the main screen, we want to draw some text data for each point - TCHAR szLapName[256]; - pLap->GetString(szLapName, NUMCHARS(szLapName)); // <-- gets the string "10:11:12 - 1:40.59 - Keith", aka the "lap name" - - float dTimeToHighlight = m_pLapSupplier->GetLapHighlightTime(pLap); // <-- asks the ILapSupplier interface what we should highlight - - TCHAR szTypeX[256]; - ::GetDataChannelName(eX,szTypeX,NUMCHARS(szTypeX)); // <-- converts the data channel type into a string, like "Oil Temperature" - - TCHAR szTypeY[256]; - ::GetDataChannelName(lstMousePointsToDraw[x].m_eChannelY, szTypeY, NUMCHARS(szTypeY)); // <-- converts the y channel into a string - - char szYString[256]; - GetChannelString(lstMousePointsToDraw[x].m_eChannelY, sfLapOpts.eUnitPreference, pDataY->GetValue(dTimeToHighlight), szYString, NUMCHARS(szYString)); - // <-- gets the actual unit string for the data channel. For speed, this might be "100.0km/h" - - char szXString[256]; - GetChannelString(eX, sfLapOpts.eUnitPreference, pDataX->GetValue(dTimeToHighlight), szXString, NUMCHARS(szXString)); - // <-- same for x channel - - char szText[256]; - sprintf(szText, "%S - (%S @ %S) %s @ %s", szLapName, szTypeY, szTypeX, szYString, szXString); - - DrawText(100.0,(x+1)*GetWindowFontSize(),szText); // <-- draws the text from the bottom of the window, working upwards - - // we also want to draw a highlighted square -// DrawGLFilledSquare(ptWindow.x, ptWindow.y, 5); // <-- draws the stupid little box at ptWindow.x. Commented out by KDJ - // we also want to draw a highlighted LINE for that individual lap/graph combination - glLineWidth(1); // Added by KDJ. Skinny line for Distance markers. - glBegin(GL_LINE_STRIP); // Added by KDJ - glVertex3f(ptWindow.x, 0, 0); // Added by KDJ, modified by Chas - glVertex3f(ptWindow.x,rcSpot.bottom,0); // Added by KDJ - glEnd(); // Added by KDJ - } -} -*/ - // Draws an oval centered at (x_center, y_center) and is is bound inside a rectangle whose width is w and height is h. void CLapPainter::drawOval (float x_center, float y_center, float w, float h) { @@ -1225,34 +1331,57 @@ void CLapPainter::drawOval (float x_center, float y_center, float w, float h) void CLapPainter::MakeColor(const CExtendedLap* pLap, bool RefLapFlag, float* pR, float* pG, float* pB) { srand((int)pLap); // <-- makes sure that we randomize the colours consistently, so that lap plots don't change colour from draw to draw... + + // Background color options: 0 (00),0,0 (Black) or 0.95 (F2),0.95.0.95 (Lt. Grey) + // Need to check contrast ratio before allowing the color + // Contrast ratio is defined as Luminace ratio L1/L2 + // Luminance = (0.2126 × red) + (0.7152 × green) + (0.0722 × blue) + // Hexadecimal value of colour component (00-FF) + if (m_pLapSupplier->GetDisplayOptions().fColorScheme) // Background color is black, make sure there is enough contrast with the lines { + float fLBackground = (0.2126 * 0.05) + (0.7152 * 0.05) + (0.0722 * 0.05); // Background Luminace value is zero (black) + float fLForeground; + float fContrastRatio; + do { *pR = RandDouble(); *pG = RandDouble(); *pB = RandDouble(); + // Contrast Ratio is (L1 + 0.05) / (L2 + 0.05) where L1 is the relative luminance of the lighter of the colors, + // L2 is the relative luminance of the darker of the colors. Contrast ratios can range from 1 to 21 (commonly written 1:1 to 21:1) + fLForeground = (0.2126 * *pR) + (0.7152 * *pG) + (0.0722 * *pB); + fContrastRatio = (fLForeground + 0.05) / (fLBackground + 0.05); } - while(*pR + *pG + *pB < 0.5); + while(fContrastRatio < 4.5 ); // Cinema standard is for greater than 4.5 to 1 contrast ratio glColor3d( *pR, *pG, *pB ); // Final color to use. Tells opengl to draw the following in the colour we just made up } - else + else // Background color is light grey, keep these colors low enough alpha to provide contrast { + // Calculate the Background Luminace value + float fLBackground = (0.2126 * 0.95) + (0.7152 * 0.95) + (0.0722 * 0.95); + float fLForeground; + float fContrastRatio; do { *pR = RandDouble(); *pG = RandDouble(); *pB = RandDouble(); + // Contrast Ratio is (L1 + 0.05) / (L2 + 0.05) where L1 is the relative luminance of the lighter of the colors, + // L2 is the relative luminance of the darker of the colors. Contrast ratios can range from 1 to 21 (commonly written 1:1 to 21:1) + fLForeground = (0.2126 * *pR) + (0.7152 * *pG) + (0.0722 * *pB); + fContrastRatio = (fLBackground + 0.05) / (fLForeground + 0.05); } - while(*pR + *pG + *pB > 2.5); + while(fContrastRatio < 3.5 ); // Cinema standard is for greater than 4.5 to 1 contrast ratio glColor3d( *pR, *pG, *pB ); // Final color to use. Tells opengl to draw the following in the colour we just made up } // Check if this the is the Reference Lap. If so, change the color to full White/Black if (RefLapFlag && m_pLapSupplier->GetDisplayOptions().fColorScheme) // Background color is black, make Reference Lap white { - *pR = 0.95; *pG = 0.95; *pB = 0.95; + *pR = 0.90; *pG = 0.90; *pB = 0.90; } - else if (RefLapFlag) // Background color is black, make Reference Lap white + else if (RefLapFlag) // Background color is Grey, make Reference Lap Black { *pR = 0.0; *pG = 0.0; *pB = 0.0; } @@ -1340,6 +1469,7 @@ void CLapPainter::DrawLapLines(const LAPSUPPLIEROPTIONS& sfLapOpts) GLdouble rgModelviewMatrix[16]; GLdouble rgProjMatrix[16]; GLint rgViewport[4]; + vector lstLaps = m_pLapSupplier->GetLapsToShow(); // Moved up-code to allow for Reference lap zooming { // Now that the matrices are correct, let's graph them. @@ -1357,7 +1487,6 @@ void CLapPainter::DrawLapLines(const LAPSUPPLIEROPTIONS& sfLapOpts) // the mouse is in our window, so let's enable panning and zooming! const double dTranslateShiftX = (rcAllLaps.left + rcAllLaps.right)/2; const double dTranslateShiftY = (rcAllLaps.top + rcAllLaps.bottom)/2; - double dScaleAmt = pow(1.1,sfLapOpts.iZoomLevels); GLdouble dXShift,dYShift,dZ; // Project the window shift stuff so we know how far to translate the view @@ -1374,6 +1503,45 @@ void CLapPainter::DrawLapLines(const LAPSUPPLIEROPTIONS& sfLapOpts) glGetDoublev(GL_PROJECTION_MATRIX, rgProjMatrix); glGetIntegerv(GL_VIEWPORT, rgViewport); } + else if(dScaleAmt > 1) // If image is Zoomed In, center the panning of the secondary display (map) to the highlighted point of the Reference Lap + { + // the mouse outside our window, let's match the zooming of the main display and pan to the highlighted location + const double dTranslateShiftX = (rcAllLaps.left + rcAllLaps.right)/2; + const double dTranslateShiftY = (rcAllLaps.top + rcAllLaps.bottom)/2; + CExtendedLap* pLap; + if (lstLaps.size() > 0) + { + pLap = lstLaps[lstLaps.size() - 1]; // Get the Reference Lap for scaling + } + else + { + return; + } + const vector& lstPoints = pLap->GetPoints(); // Get the list of point for the Reference Lap + float dBestLength = -1; + TimePoint2D ptBest; // Best highlighted point where the mouse is on the Reference Lap + for(int x = 0; x< lstPoints.size(); x++) + { + const TimePoint2D& p = lstPoints[x]; + glVertex2f(p.flX,p.flY); + int iTime = m_pLapSupplier->GetLapHighlightTime(pLap); + if(abs(p.iTime - iTime) < dBestLength || dBestLength < 0) + { + dBestLength = abs(p.iTime - iTime); + ptBest = p; // ptBest contains the X/Y values for the highlighted point of the Reference Lap + } + } + // Set up to perform the ZOOM function for MAP. + glTranslated(dTranslateShiftX, dTranslateShiftY, 0); // Translate the map to origin + glScaled(dScaleAmt*1.5, dScaleAmt*1.5, 1.0f); // Scale the sucker + glTranslated(-dTranslateShiftX, -dTranslateShiftY, 0); // Now put the map back in its place + + glTranslated(dTranslateShiftX-(double)ptBest.flX, dTranslateShiftY-(double)ptBest.flY, 0); // Now move the map to the highlighted location + // now having shifted, let's get our new model matrices + glGetDoublev(GL_MODELVIEW_MATRIX, rgModelviewMatrix); + glGetDoublev(GL_PROJECTION_MATRIX, rgProjMatrix); + glGetIntegerv(GL_VIEWPORT, rgViewport); + } } POINT ptMouse; Vector2D vHighlight; @@ -1387,7 +1555,6 @@ void CLapPainter::DrawLapLines(const LAPSUPPLIEROPTIONS& sfLapOpts) } vector lstMousePointsToDraw; - vector lstLaps = m_pLapSupplier->GetLapsToShow(); for(int x = 0; x < lstLaps.size(); x++) { CExtendedLap* pLap = lstLaps[x]; @@ -1580,6 +1747,9 @@ void CLapPainter::fBoxMovingAvg( int n, vector& lstPoints, int w, vec if (a < 0) aTemp = 0; else if (a >= n) aTemp = n - 1; else aTemp = a; t += lstPoints[aTemp].flValue; } - lstSmoothPts[s].flValue = t / ( 2 * w + 1 ); + DataPoint tempDataPoint; + tempDataPoint.flValue = (t / ( 2 * w + 1 )); + tempDataPoint.iTimeMs = lstPoints[s].iTimeMs; + lstSmoothPts.push_back( tempDataPoint ); } } diff --git a/PitsideConsole/PitsideConsole/LapPainter.h b/PitsideConsole/PitsideConsole/LapPainter.h index 49b3560..350bfaa 100644 --- a/PitsideConsole/PitsideConsole/LapPainter.h +++ b/PitsideConsole/PitsideConsole/LapPainter.h @@ -28,7 +28,9 @@ enum SUPPLIERID SUPPLIERID_MAINDISPLAY, SUPPLIERID_SUBDISPLAY, SUPPLIERID_SECTORDISPLAY, - SUPPLIERID_TRACTIONCIRCLEDISPLAY, // Draw the traction + SUPPLIERID_TRACTIONCIRCLEDISPLAY, // Draw the traction circle + SUPPLIERID_ALLDATADISPLAY, // Show a window with all data for that lap for the given point +// SUPPLIERID_SUBWINDOW, }; enum LAPDISPLAYSTYLE @@ -38,7 +40,8 @@ enum LAPDISPLAYSTYLE LAPDISPLAYSTYLE_NOLAPS, // what we display if there are no laps selected LAPDISPLAYSTYLE_RECEPTION, // display a map of wireless reception data LAPDISPLAYSTYLE_COUNT, - LAPDISPLAYSTYLE_TRACTIONCIRCLE, // Draw the traction + LAPDISPLAYSTYLE_TRACTIONCIRCLE, // Draw the traction circle + LAPDISPLAYSTYLE_ALLDATADISPLAY, // Draw the data window for given point }; // LapSupplier interface - needed so that the lap painter knows what to paint interface ILapSupplier @@ -94,12 +97,10 @@ class CLapPainter : public ArtOpenGLWindow void DrawVerticalLine(double flLine, float mapMinY, float mapMaxY, char szText[512]); void fExpMovingAvg( int n, vector& lstPointsX, double alpha, vector& lstSmoothPts ); void fBoxMovingAvg( int n, vector& lstPoints, int w, vector& lstSmoothPts, bool bSmoothFlag ); - // void MagicDeterminingFunction(const LAPSUPPLIEROPTIONS& sfLapOpts, bool fHighlightXAxis); + private: ILapSupplier* m_pLapSupplier; - //ILapHighlighter* m_pHighlighter; - int m_iSupplierId; static int d; // For Value table counting //IUI* m_pUI; diff --git a/PitsideConsole/PitsideConsole/LapReceiver.cpp b/PitsideConsole/PitsideConsole/LapReceiver.cpp index 19a399a..509cc1c 100644 --- a/PitsideConsole/PitsideConsole/LapReceiver.cpp +++ b/PitsideConsole/PitsideConsole/LapReceiver.cpp @@ -70,7 +70,11 @@ void CDataChannel::DoLoad(CSfArtSQLiteDB& db, int _id) } } } - +/* +bool CReceiveLapOpts::m_Button_LiveData() +{ +} +*/ bool CDataChannel::Load(CSfArtSQLiteDB& db, CSfArtSQLiteQuery& dc, bool fLazyLoad) { m_db = &db; @@ -132,7 +136,21 @@ float CDataChannel::GetValue(int iTime) const int iEnd = cSize; - const DataPoint* pData = lstData.data(); + DataPoint* pData = NULL; + vector& lstPoints = lstData; + vector lstSmoothPts; + lstSmoothPts.begin(); + if ( ( eChannelType == DATA_CHANNEL_X_ACCEL || eChannelType == DATA_CHANNEL_Y_ACCEL || eChannelType == DATA_CHANNEL_Z_ACCEL ) ) + { + lstSmoothPts.clear(); + fBoxMovingAvg( lstPoints.size(), lstPoints, (int) lstPoints.size() / 400, lstSmoothPts ); + pData = lstSmoothPts.data(); + } + else + { + pData = lstData.data(); + } + // this binary search will find the first and second points that we should use for interpolation. const DataPoint* dataFirst = NULL; const DataPoint* dataSecond = NULL; @@ -183,43 +201,94 @@ float CDataChannel::GetValue(int iTime) const const float flFirst = dataFirst->flValue; const float flNext = dataSecond->flValue; const float flOffset = iTime - dataFirst->iTimeMs; - const float flWidth = dataSecond->iTimeMs - dataFirst->iTimeMs; - if(flWidth == 0) return flFirst; - const float flPct = flOffset / flWidth; - return (1-flPct)*flFirst + (flPct)*flNext; + const float flWidth = dataSecond->iTimeMs - dataFirst->iTimeMs; + if(flWidth == 0) + { + if ( (eChannelType == DATA_CHANNEL_X_ACCEL || eChannelType == DATA_CHANNEL_Y_ACCEL || eChannelType == DATA_CHANNEL_Z_ACCEL ) ) + { + return SmoothedFilter().ApplyTo(flFirst); // Returns the first value, transformed Y-value for this data channel + } + else + { + return flFirst; // Returns the first value for the Y-value for this data channel + } + } + + const float flPct = flOffset / flWidth; + if (eChannelType == DATA_CHANNEL_X_ACCEL || eChannelType == DATA_CHANNEL_Y_ACCEL || eChannelType == DATA_CHANNEL_Z_ACCEL ) + { + return SmoothedFilter().ApplyTo( (1-flPct)*flFirst + (flPct)*flNext ); // Returns the transformed Y-value for this data channel + } + else + { + return (1-flPct)*flFirst + (flPct)*flNext; // Returns the interpolated Y-value for this data channel + } } else { - return pData[iCheck].flValue; + if (eChannelType == DATA_CHANNEL_X_ACCEL || eChannelType == DATA_CHANNEL_Y_ACCEL || eChannelType == DATA_CHANNEL_Z_ACCEL ) + { + return SmoothedFilter().ApplyTo( pData[iCheck].flValue ); // Returns the last value for the Y-value for this data channel + } + else + { + return pData[iCheck].flValue; // Returns the last value for the Y-value for this data channel + } } } return 0; } + float CDataChannel::GetValue(int iTime, const vector::const_iterator& i) const { CheckLazyLoad(); DASSERT(fLocked); // you should only be getting data after the channel is all loaded up! const DataPoint& data = (*i); DASSERT(data.iTimeMs >= iTime); - if(i != lstData.begin()) + if(i != lstData.begin() ) + // if(i != lstData.begin() && (eChannelType != DATA_CHANNEL_X_ACCEL || eChannelType != DATA_CHANNEL_Y_ACCEL || eChannelType != DATA_CHANNEL_Z_ACCEL ) && sfLapOpts.bSmoothYesNo == true ) { // this iterator has been moved forward from the start of the vector. // back up one from it, then interpolate between those two points vector::const_iterator iBack = i; iBack--; const DataPoint& dataLast = *iBack; - if(dataLast.iTimeMs == data.iTimeMs) return dataLast.flValue; + if(dataLast.iTimeMs == data.iTimeMs) + { + if ( (eChannelType == DATA_CHANNEL_X_ACCEL || eChannelType == DATA_CHANNEL_Y_ACCEL || eChannelType == DATA_CHANNEL_Z_ACCEL ) ) + { + return SmoothedFilter().ApplyTo( dataLast.flValue ); // Returns the last value for the Y-value for this data channel + } + else + { + return dataLast.flValue; + } + } float flWidth = data.iTimeMs - dataLast.iTimeMs; float flOffset = iTime - dataLast.iTimeMs; float flPct = flOffset / flWidth; DASSERT(flPct >= 0.0f && flPct <= 1.0f); - return (1-flPct)*dataLast.flValue + flPct * data.flValue; + if (eChannelType == DATA_CHANNEL_X_ACCEL || eChannelType == DATA_CHANNEL_Y_ACCEL || eChannelType == DATA_CHANNEL_Z_ACCEL ) + { + return SmoothedFilter().ApplyTo( (1-flPct)*dataLast.flValue + flPct * data.flValue ); // Returns the last value for the Y-value for this data channel + } + else + { + return (1-flPct)*dataLast.flValue + flPct * data.flValue; + } } else { // this iterator is actually the first element in our vector, so just return it's value - return data.flValue; + if (eChannelType == DATA_CHANNEL_X_ACCEL || eChannelType == DATA_CHANNEL_Y_ACCEL || eChannelType == DATA_CHANNEL_Z_ACCEL ) + { + return SmoothedFilter().ApplyTo( data.flValue ); + } + else + { + return data.flValue; + } } } float CDataChannel::GetMin() const @@ -421,6 +490,20 @@ void GetIPString(DWORD ip, LPTSTR lpsz, int cchBuf) swprintf(lpsz, cchBuf, L"%d.%d.%d.%d",pBytes[0],pBytes[1],pBytes[2],pBytes[3]); } +int str_ends_with2(const TCHAR * str, const TCHAR * suffix) +{ + if( str == NULL || suffix == NULL ) + return 0; + + size_t str_len = wcslen(str); + size_t suffix_len = wcslen(suffix); + + if(suffix_len > str_len) + return 0; + + return 0 == wcsncmp( str + str_len - suffix_len, suffix, suffix_len ); +} + int TimeoutRead(SOCKET s, char* buf, int cbBuf, int flags, int timeout, bool* pfConnectionLost) { *pfConnectionLost = false; @@ -496,111 +579,150 @@ class LapSocketReceiver char buf[1024]; bool fConnectionLost = false; int cbRead = TimeoutRead(sData,buf,sizeof(buf),0,10000, &fConnectionLost); +// CReceiveLapOpts::m_pLapSupplier()->GetDisplayOptions().; +// bool b_ButtonLiveData = CReceiveLapOpts::m_pLapSupplier->; if(cbRead <= 0 || fConnectionLost) { pLaps->SetNetStatus(NETSTATUS_STATUS, L"Probably lost connection"); pLaps->SetNetStatus(NETSTATUS_REMOTEIP, L""); break; } + else if (int b_Button_LiveData =! true) // Check if user wants to disable live data collection for lap processing + { + pLaps->SetNetStatus(NETSTATUS_STATUS, L"Data reception disabled"); + pLaps->SetNetStatus(NETSTATUS_REMOTEIP, L""); + break; + } else { for(int x = 0;x < cbRead; x++) { - lstLapBuf.push_back(buf[x]); - if(aV1Start.Process(buf[x])) - { - eRecv = RECV_V1_LAP; - aV1Start.Reset(); - // we have detected the start of a new lap - lstLapBuf.clear(); - } - if(aV1End.Process(buf[x])) - { - eRecv = RECV_NONE; - aV1End.Reset(); - // we have found the end of a lap - int iLapId = 0; - ILap* pLap = pLaps->AllocateLap(true); - if(ProcessV1LapData(lstLapBuf, &iLapId, pLap)) - { - pLaps->AddLap(pLap, 0xffffffff); - } - else - { - pLap->Free(); - } - lstLapBuf.clear(); - } - if(aV2Start.Process(buf[x])) - { - eRecv = RECV_V2_LAP; - aV2Start.Reset(); - lstLapBuf.clear(); - } - if(aV2End.Process(buf[x])) - { - eRecv = RECV_NONE; - aV2End.Reset(); - int iLapId = 0; - ILap* pLap = pLaps->AllocateLap(true); - if(ProcessV2LapData(lstLapBuf, &iLapId, pLap)) - { - pLaps->AddLap(pLap, 0xffffffff); - } - } - - lstDataBuf.push_back(buf[x]); - if(aDataStart.Process(buf[x])) - { - eRecv = RECV_DATA; - aDataStart.Reset(); - lstDataBuf.clear(); - } - if(aDataEnd.Process(buf[x])) - { - eRecv = RECV_NONE; - int iLapId = 0; - aDataEnd.Reset(); - IDataChannel* pDataChannel = pLaps->AllocateDataChannel(); - if(ProcessDataChannel(lstDataBuf,&iLapId, pDataChannel)) - { - pLaps->AddDataChannel(pDataChannel); - } - lstDataBuf.clear(); - } + lstLapBuf.push_back(buf[x]); + if(aV1Start.Process(buf[x])) + { + eRecv = RECV_V1_LAP; + aV1Start.Reset(); + // we have detected the start of a new lap + lstLapBuf.clear(); + } + if(aV1End.Process(buf[x])) + { + eRecv = RECV_NONE; + aV1End.Reset(); + // we have found the end of a lap + int iLapId = 0; + ILap* pLap = pLaps->AllocateLap(true); + if(ProcessV1LapData(lstLapBuf, &iLapId, pLap)) + { + pLaps->AddLap(pLap, 0xffffffff); + } + else + { + pLap->Free(); + } + lstLapBuf.clear(); + } + if(aV2Start.Process(buf[x])) + { + eRecv = RECV_V2_LAP; + aV2Start.Reset(); + lstLapBuf.clear(); + } + if(aV2End.Process(buf[x])) + { + eRecv = RECV_NONE; + aV2End.Reset(); + int iLapId = 0; + ILap* pLap = pLaps->AllocateLap(true); + if(ProcessV2LapData(lstLapBuf, &iLapId, pLap)) + { + pLaps->AddLap(pLap, 0xffffffff); + } + } + + lstDataBuf.push_back(buf[x]); + if(aDataStart.Process(buf[x])) + { + eRecv = RECV_DATA; + aDataStart.Reset(); + lstDataBuf.clear(); + } + if(aDataEnd.Process(buf[x])) + { + eRecv = RECV_NONE; + int iLapId = 0; + aDataEnd.Reset(); + IDataChannel* pDataChannel = pLaps->AllocateDataChannel(); + if(ProcessDataChannel(lstDataBuf,&iLapId, pDataChannel)) + { + pLaps->AddDataChannel(pDataChannel); + } + lstDataBuf.clear(); + } - if(aHTBT.Process(buf[x])) - { - eRecv = RECV_NONE; - aHTBT.Reset(); - const char* pbResponse = "HTBT"; - send(sData, pbResponse, 4, 0); - - lstLapBuf.clear(); - lstDataBuf.clear(); - } - lstDBBuf.push_back(buf[x]); - - if(aDBIncoming.Process(buf[x])) - { - eRecv = RECV_DB; - lstDBBuf.clear(); - } - if(aDBDone.Process(buf[x])) - { - eRecv = RECV_NONE; - // we have received a raw database. Save it to a temp folder, then send the path to the pitside UI so it can decide what to do - TCHAR szTemp[MAX_PATH]; - if(GetTempPath(MAX_PATH, szTemp)) - { - wcscat(szTemp,L"TempPitsideDB.wflp"); - if(SaveBufferToFile(szTemp, &lstDBBuf[0], lstDBBuf.size()-aDBDone.GetSize())) - { - pLaps->NotifyDBArrival(szTemp); - } - } - - } + if(aHTBT.Process(buf[x])) + { + eRecv = RECV_NONE; + aHTBT.Reset(); + const char* pbResponse = "HTBT"; + send(sData, pbResponse, 4, 0); + + lstLapBuf.clear(); + lstDataBuf.clear(); + } + lstDBBuf.push_back(buf[x]); + + if(aDBIncoming.Process(buf[x])) + { + eRecv = RECV_DB; + lstDBBuf.clear(); + } + if(aDBDone.Process(buf[x])) + { + eRecv = RECV_NONE; + // First, let the user know that the database has been recieved and determine where to save it + DWORD dwRet = MessageBox(NULL,L"A new database has been sent from a phone.\n\nSpecify a name and folder to save it to",L"New database",MB_OK); + + // we have received a raw database. Select a folder to save it to, then send the path to the pitside UI so it can decide what to do + TCHAR szDBPath[MAX_PATH] = {NULL}; + wcscat(szDBPath,L"TempPitsideDB.wflp"); + while (true) + { + if(ArtGetSaveFileName(NULL,L"Select location and filename to save to",szDBPath,NUMCHARS(szDBPath),L"WifiLapper Files (*.wflp)\0*.WFLP\0\0")) + { + // let's make sure there's a .wflp suffix on that bugger. + if(!str_ends_with2(szDBPath,L".wflp") && !str_ends_with2(szDBPath,L".WFLP")) + { + wcsncat(szDBPath,L".wflp", NUMCHARS(szDBPath)); + } + const bool fFileIsNew = !DoesFileExist(szDBPath); + if(fFileIsNew) + { + break; // Exit loop, as file name is valid and new + } + else + { + DWORD dwRet = MessageBox(NULL,L"A database already exists with that name.\n\nAre you sure you want to overwrite it?",L"WARNING", MB_APPLMODAL | MB_ICONWARNING | MB_YESNO | MB_TOPMOST | MB_DEFBUTTON2); + if (dwRet == IDYES) + { + break; // User wants to overwrite file, so exit loop and proceed + } + } + } + else + { + return; // User cancelled the save operation, so leave subroutine + } + } + if(SaveBufferToFile(szDBPath, &lstDBBuf[0], lstDBBuf.size()-aDBDone.GetSize())) + { + pLaps->NotifyDBArrival(szDBPath); + } + else + { + MessageBox(NULL,L"An error occurred while saving the database",L"ERROR",MB_APPLMODAL | MB_ICONERROR | MB_TOPMOST | MB_OK); + } + } } // end processing loop @@ -651,7 +773,7 @@ class LapSocketReceiver { Sleep(1); // let's let the buffer fill up } - } + } } if(sData != INVALID_SOCKET) @@ -710,43 +832,43 @@ bool ReceiveLaps(int iPort, ILapReceiver* pLaps) closesocket(aSocket); aSocket = INVALID_SOCKET; } - else - { - sockaddr sfAddr = {0}; - int cbAddr = sizeof(sfAddr); - TCHAR szIPString[512] = {0}; - pLaps->SetNetStatus(NETSTATUS_STATUS, L"Waiting for incoming connection to accept"); - sDataSocket = accept(aSocket, &sfAddr, &cbAddr); - if(sDataSocket != INVALID_SOCKET) - { - sockaddr_in* pIn = (sockaddr_in*)&sfAddr; - pLaps->SetNetStatus(NETSTATUS_STATUS, L"Connected"); - - TCHAR szIPString[512] = L""; - GetIPString(pIn->sin_addr.S_un.S_addr, szIPString, NUMCHARS(szIPString)); - pLaps->SetNetStatus(NETSTATUS_REMOTEIP, szIPString); + else + { + sockaddr sfAddr = {0}; + int cbAddr = sizeof(sfAddr); + TCHAR szIPString[512] = {0}; + pLaps->SetNetStatus(NETSTATUS_STATUS, L"Waiting for incoming connection to accept"); + sDataSocket = accept(aSocket, &sfAddr, &cbAddr); + if(sDataSocket != INVALID_SOCKET) + { + sockaddr_in* pIn = (sockaddr_in*)&sfAddr; + pLaps->SetNetStatus(NETSTATUS_STATUS, L"Connected"); + + TCHAR szIPString[512] = L""; + GetIPString(pIn->sin_addr.S_un.S_addr, szIPString, NUMCHARS(szIPString)); + pLaps->SetNetStatus(NETSTATUS_REMOTEIP, szIPString); - new LapSocketReceiver(pLaps, sDataSocket); // creates the guy that will actually receive this data (and close the socket when he's done) + new LapSocketReceiver(pLaps, sDataSocket); // creates the guy that will actually receive this data (and close the socket when he's done) - { - sockaddr sfName = {0}; - int cbName = sizeof(sfName); - getsockname(sDataSocket, &sfName, &cbName); + { + sockaddr sfName = {0}; + int cbName = sizeof(sfName); + getsockname(sDataSocket, &sfName, &cbName); - pIn = (sockaddr_in*)&sfName; - GetIPString(pIn->sin_addr.S_un.S_addr, szIPString, NUMCHARS(szIPString)); - pLaps->SetNetStatus(NETSTATUS_THISIP, szIPString); - } - } - else - { - sockaddr sfName = {0}; - TCHAR szIPString[512] = {0}; - sockaddr_in* pIn = (sockaddr_in*)&sfName; - GetIPString(pIn->sin_addr.S_un.S_addr, szIPString, NUMCHARS(szIPString)); - pLaps->SetNetStatus(NETSTATUS_REMOTEIP, szIPString); - } + pIn = (sockaddr_in*)&sfName; + GetIPString(pIn->sin_addr.S_un.S_addr, szIPString, NUMCHARS(szIPString)); + pLaps->SetNetStatus(NETSTATUS_THISIP, szIPString); + } + } + else + { + sockaddr sfName = {0}; + TCHAR szIPString[512] = {0}; + sockaddr_in* pIn = (sockaddr_in*)&sfName; + GetIPString(pIn->sin_addr.S_un.S_addr, szIPString, NUMCHARS(szIPString)); + pLaps->SetNetStatus(NETSTATUS_REMOTEIP, szIPString); + } } } } @@ -880,12 +1002,7 @@ DWORD LoadFromSQLiteThreadProc(LPVOID pvParam) return 0; } -void LoadFromSQLite -( - LPCTSTR lpszSQL, - int iRaceId, - ILapReceiver* pRecv -) +void LoadFromSQLite( LPCTSTR lpszSQL, int iRaceId, ILapReceiver* pRecv ) { DASSERT(iRaceId >= 0); @@ -900,3 +1017,29 @@ void LoadFromSQLite WaitForSingleObject(hThread, INFINITE); } } + +// * Moving average function +// * n is the number of input samples +// * v is an array of values of size n +// * w is the size of the window, taken on each side of sample +// * out is output array of size n +// * +// +void fBoxMovingAvg( int n, vector& lstPoints, int w, vector& lstSmoothPts ) +{ + int s; + for(s=0; s < n; s++) + { + float t = 0.0; + int aTemp = 0; + for ( int a = s - w; a <= s + w; a++ ) + { + if (a < 0) aTemp = 0; else if (a >= n) aTemp = n - 1; else aTemp = a; + t += lstPoints[aTemp].flValue; + } + DataPoint tempDataPoint; + tempDataPoint.flValue = (t / ( 2 * w + 1 )); + tempDataPoint.iTimeMs = lstPoints[s].iTimeMs; + lstSmoothPts.push_back( tempDataPoint ); + } +} diff --git a/PitsideConsole/PitsideConsole/LapReceiver.h b/PitsideConsole/PitsideConsole/LapReceiver.h index e87ff78..c990c51 100644 --- a/PitsideConsole/PitsideConsole/LapReceiver.h +++ b/PitsideConsole/PitsideConsole/LapReceiver.h @@ -1,402 +1,493 @@ -#pragma once - -#include -#include -#include -#include "ArtVector.h" -#include "ArtTools.h" -#include -#include "ArtSQL/ArtSQLite.h" - -using namespace std; - -struct TimePoint2D -{ -public: - TimePoint2D() {} - TimePoint2D(const TimePoint2D* pToFlip) // flips all the input bits - { - flX = FLIPBITS(pToFlip->flX); - flY = FLIPBITS(pToFlip->flY); - iTime = FLIPBITS(pToFlip->iTime); - flVelocity = FLIPBITS(pToFlip->flVelocity); - flSum = FLIPBITS(pToFlip->flSum); - } - bool IsValid() - { - float flComputedSum = flX + flY; - if(flSum == flComputedSum) return true; - return false; - } - bool operator != (const TimePoint2D& pt) const - { - return flX != pt.flX || flY != pt.flY || iTime != pt.iTime || flVelocity != pt.flVelocity; - } - - // flWeight: 0.0 -> entirely pt1. 1.0 -> entirely pt2. 0.5 -> normal averaging - static TimePoint2D Average(const TimePoint2D& pt1, const TimePoint2D& pt2, float flWeight) - { - float fl1Minus = 1.0f - flWeight; - TimePoint2D ptRet; - ptRet.flVelocity = fl1Minus*pt1.flVelocity + flWeight*pt2.flVelocity; - ptRet.flX = fl1Minus*pt1.flX + flWeight*pt2.flX; - ptRet.flY = fl1Minus*pt1.flY + flWeight*pt2.flY; - ptRet.iTime = (int)(fl1Minus*pt1.iTime + flWeight*pt2.iTime); - ptRet.flSum = (ptRet.flX + ptRet.flY); - return ptRet; - } - Vector2D operator - (const TimePoint2D& pt) const - { - Vector2D ret; - ret.m_v[0] = flX - pt.flX; - ret.m_v[1] = flY - pt.flY; - return ret; - } - Vector2D V2D() const - { - Vector2D ret; - ret.m_v[0] = flX; - ret.m_v[1] = flY; - return ret; - } - - float flX; - float flY; - int iTime; // the time since the phone app started that this point was received (in milliseconds) - float flVelocity; - float flSum; -}; - -struct DataPoint -{ - DataPoint() : flValue(0),iTimeMs(0) {} - DataPoint(int iTimeMs, float flValue) : flValue(flValue),iTimeMs(iTimeMs) {} - float flValue; - int iTimeMs; -}; - -enum DATA_CHANNEL; -struct InputChannelRaw -{ - int iLapId; - int eChannelType; - int cPoints; - DataPoint rgPoints[1]; -}; - -struct V1InputLapRaw -{ - int iLapId; - int cCount; - float dTime; - int iStartTime; // start time of the lap in unix time (seconds since 1970) - float rgSF[12]; // the 6 points (in 3 pairs) designating split 1, split 2, and start/finish. - float rgSFDir[6]; // the 3 vectors (x1,y1,x2,y2,x3,y3) showing direction of the SF lines - TimePoint2D rgPoints[1]; -}; -struct V2InputLapRaw -{ - int iVersion_1; // redundant versions. we don't want to get it wrong - int iVersion_2; - int iCarNumber; - int iSecondaryCarNumber; - int iLapId; - int cCount; - float dTime; - int iStartTime; // start time of the lap in unix time (seconds since 1970) - float rgSF[12]; // the 6 points (in 3 pairs) designating split 1, split 2, and start/finish. - float rgSFDir[6]; // the 3 vectors (x1,y1,x2,y2,x3,y3) showing direction of the SF lines - TimePoint2D rgPoints[1]; -}; - -class IDataChannel -{ -public: - virtual void Load(InputChannelRaw* pData) = 0; - virtual bool Load(CSfArtSQLiteDB& db, CSfArtSQLiteQuery& dc, bool fLazyLoad) = 0; - virtual void Init(int iLapId, DATA_CHANNEL eChannel) = 0; - virtual bool IsValid() const = 0; - virtual bool IsSameChannel(const IDataChannel* pOther) const = 0; - - virtual int GetLapId() const = 0; - - // random-access version: slower - virtual float GetValue(int iTime) const = 0; - // the iterator points to the DataPoint with time greater than the current time - virtual float GetValue(int iTime, const vector::const_iterator& i) const = 0; - virtual float GetMin() const = 0; - virtual float GetMax() const = 0; - virtual int GetEndTimeMs() const = 0; - virtual int GetStartTimeMs() const = 0; - - virtual const vector& GetData() const = 0; - - virtual void AddPoint(int iTime, float flValue) = 0; - virtual DATA_CHANNEL GetChannelType() const = 0; - // when you lock a data channel, it means that no more points may be added to it ever. - // it also sorts the vector - virtual void Lock() = 0; - virtual bool IsLocked() const = 0; -}; -class CDataChannel : public IDataChannel -{ -public: - CDataChannel(); - virtual ~CDataChannel(); - - void Load(InputChannelRaw* pData) override; - bool Load(CSfArtSQLiteDB& db, CSfArtSQLiteQuery& dc, bool fLazyLoad) override; - void Init(int iLapId, DATA_CHANNEL eChannel) override; - bool IsValid() const override; - bool IsSameChannel(const IDataChannel* pOther) const override; - - int GetLapId() const override; - - // random-access version: slower - float GetValue(int iTime) const override; - // the iterator points to the DataPoint with time greater than the current time - float GetValue(int iTime, const vector::const_iterator& i) const override; - float GetMin() const override; - float GetMax() const override; - int GetEndTimeMs() const override; - int GetStartTimeMs() const override; - - const vector& GetData() const override {return lstData;} - - void AddPoint(int iTime, float flValue) override; // iTime must be in milliseconds since the phone app started. flValue can be whatever you want - DATA_CHANNEL GetChannelType() const override {return eChannelType;} - // when you lock a data channel, it means that no more points may be added to it ever. - // it also sorts the vector - void Lock() override; - bool IsLocked() const override {return fLocked;} -private: - void DoLoad(CSfArtSQLiteDB& db, int channelId); - void CheckLazyLoad() const - { - CDataChannel* pChan = (CDataChannel*)this; // gross.... - if(m_fLazyLoad && !fLocked) - { - pChan->DoLoad(*m_db,m_iChannelId); - pChan->Lock(); - } - } -private: - int m_iChannelId; - - bool fLocked; - int iLapId; - DATA_CHANNEL eChannelType; - mutable vector lstData; - - float m_dMin; - float m_dMax; - - int m_msMin; // start time (milliseconds since app start) - int m_msMax; // end time (milliseconds since app start) - - bool m_fLazyLoad; - mutable CSfArtSQLiteDB* m_db; -}; - - -class StartFinish +#pragma once + +#include +#include +#include +#include "ArtVector.h" +#include "ArtTools.h" +#include +#include "ArtSQL/ArtSQLite.h" +#include "PitsideConsole.h" +//#include "DlgPlotSelect.h" +//#include "LapPainter.h" + +using namespace std; + +struct TimePoint2D +{ +public: + TimePoint2D() {} + TimePoint2D(const TimePoint2D* pToFlip) // flips all the input bits + { + flX = FLIPBITS(pToFlip->flX); + flY = FLIPBITS(pToFlip->flY); + iTime = FLIPBITS(pToFlip->iTime); + flVelocity = FLIPBITS(pToFlip->flVelocity); + flSum = FLIPBITS(pToFlip->flSum); + } + bool IsValid() + { + float flComputedSum = flX + flY; + if(flSum == flComputedSum) return true; + return false; + } + bool operator != (const TimePoint2D& pt) const + { + return flX != pt.flX || flY != pt.flY || iTime != pt.iTime || flVelocity != pt.flVelocity; + } + + // flWeight: 0.0 -> entirely pt1. 1.0 -> entirely pt2. 0.5 -> normal averaging + static TimePoint2D Average(const TimePoint2D& pt1, const TimePoint2D& pt2, float flWeight) + { + float fl1Minus = 1.0f - flWeight; + TimePoint2D ptRet; + ptRet.flVelocity = fl1Minus*pt1.flVelocity + flWeight*pt2.flVelocity; + ptRet.flX = fl1Minus*pt1.flX + flWeight*pt2.flX; + ptRet.flY = fl1Minus*pt1.flY + flWeight*pt2.flY; + ptRet.iTime = (int)(fl1Minus*pt1.iTime + flWeight*pt2.iTime); + ptRet.flSum = (ptRet.flX + ptRet.flY); + return ptRet; + } + Vector2D operator - (const TimePoint2D& pt) const + { + Vector2D ret; + ret.m_v[0] = flX - pt.flX; + ret.m_v[1] = flY - pt.flY; + return ret; + } + Vector2D V2D() const + { + Vector2D ret; + ret.m_v[0] = flX; + ret.m_v[1] = flY; + return ret; + } + + float flX; + float flY; + int iTime; // the time since the phone app started that this point was received (in milliseconds) + float flVelocity; + float flSum; +}; + +struct DataPoint +{ + DataPoint() : flValue(0),iTimeMs(0) {} + DataPoint(int iTimeMs, float flValue) : flValue(flValue),iTimeMs(iTimeMs) {} + float flValue; + int iTimeMs; +}; + +enum DATA_CHANNEL; +struct InputChannelRaw +{ + int iLapId; + int eChannelType; + int cPoints; + DataPoint rgPoints[1]; +}; + +struct V1InputLapRaw +{ + int iLapId; + int cCount; + float dTime; + int iStartTime; // start time of the lap in unix time (seconds since 1970) + float rgSF[12]; // the 6 points (in 3 pairs) designating split 1, split 2, and start/finish. + float rgSFDir[6]; // the 3 vectors (x1,y1,x2,y2,x3,y3) showing direction of the SF lines + TimePoint2D rgPoints[1]; +}; +struct V2InputLapRaw +{ + int iVersion_1; // redundant versions. we don't want to get it wrong + int iVersion_2; + int iCarNumber; + int iSecondaryCarNumber; + int iLapId; + int cCount; + float dTime; + int iStartTime; // start time of the lap in unix time (seconds since 1970) + float rgSF[12]; // the 6 points (in 3 pairs) designating split 1, split 2, and start/finish. + float rgSFDir[6]; // the 3 vectors (x1,y1,x2,y2,x3,y3) showing direction of the SF lines + TimePoint2D rgPoints[1]; +}; + +// CDataChannelFilter is a functino to allow for data transformations inputed by the user - KDJ +class CDataChannelFilter +{ +public: + virtual float ApplyTo(float flValue) const = 0; +}; + +class IDataChannel +{ +public: + virtual void Load(InputChannelRaw* pData) = 0; + virtual bool Load(CSfArtSQLiteDB& db, CSfArtSQLiteQuery& dc, bool fLazyLoad) = 0; + virtual void Init(int iLapId, DATA_CHANNEL eChannel) = 0; + virtual bool IsValid() const = 0; + virtual bool IsSameChannel(const IDataChannel* pOther) const = 0; + + virtual int GetLapId() const = 0; + + // random-access version: slower + virtual float GetValue(int iTime) const = 0; + // the iterator points to the DataPoint with time greater than the current time + virtual float GetValue(int iTime, const vector::const_iterator& i) const = 0; + virtual float GetMin() const = 0; + virtual float GetMax() const = 0; + virtual int GetEndTimeMs() const = 0; + virtual int GetStartTimeMs() const = 0; + + virtual const vector& GetData() const = 0; + + virtual void AddPoint(int iTime, float flValue) = 0; + virtual DATA_CHANNEL GetChannelType() const = 0; + // when you lock a data channel, it means that no more points may be added to it ever. + // it also sorts the vector + virtual void Lock() = 0; + virtual bool IsLocked() const = 0; +}; +class CDataChannel : public IDataChannel +{ +public: + CDataChannel(); + virtual ~CDataChannel(); + + void Load(InputChannelRaw* pData) override; + bool Load(CSfArtSQLiteDB& db, CSfArtSQLiteQuery& dc, bool fLazyLoad) override; + void Init(int iLapId, DATA_CHANNEL eChannel) override; + bool IsValid() const override; + bool IsSameChannel(const IDataChannel* pOther) const override; + + int GetLapId() const override; + + // random-access version: slower + float GetValue(int iTime) const override; + // the iterator points to the DataPoint with time greater than the current time + float GetValue(int iTime, const vector::const_iterator& i) const override; + float GetMin() const override; + float GetMax() const override; + int GetEndTimeMs() const override; + int GetStartTimeMs() const override; + + const vector& GetData() const override {return lstData;} + + void AddPoint(int iTime, float flValue) override; // iTime must be in milliseconds since the phone app started. flValue can be whatever you want + DATA_CHANNEL GetChannelType() const override {return eChannelType;} + // when you lock a data channel, it means that no more points may be added to it ever. + // it also sorts the vector + void Lock() override; + bool IsLocked() const override {return fLocked;} +private: + void DoLoad(CSfArtSQLiteDB& db, int channelId); + void CheckLazyLoad() const + { + CDataChannel* pChan = (CDataChannel*)this; // gross.... + if(m_fLazyLoad && !fLocked) + { + pChan->DoLoad(*m_db,m_iChannelId); + pChan->Lock(); + } + } +private: + int m_iChannelId; + + bool fLocked; + int iLapId; + DATA_CHANNEL eChannelType; + mutable vector lstData; + + float m_dMin; + float m_dMax; + + int m_msMin; // start time (milliseconds since app start) + int m_msMax; // end time (milliseconds since app start) + + bool m_fLazyLoad; + mutable CSfArtSQLiteDB* m_db; +}; + + +class StartFinish +{ +public: + StartFinish() + { + } + StartFinish(float* pPointData) + { + m_pt1.m_v[0] = pPointData[0]; + m_pt1.m_v[1] = pPointData[1]; + m_pt2.m_v[0] = pPointData[2]; + m_pt2.m_v[1] = pPointData[3]; + } + const Vector2D& GetPt1() const {return m_pt1;} + const Vector2D& GetPt2() const {return m_pt2;} +// Vector2D& GetPt1() const {return m_pt1;} +// Vector2D& GetPt2() const {return m_pt2;} +//private: // Made public by KDJ + Vector2D m_pt1; + Vector2D m_pt2; +}; + +struct CARNUMBERCOMBO +{ + int iCarNumber; + int iSecondaryCarNumber; + bool IsOldVersion() const {return iCarNumber == -1 && iSecondaryCarNumber == -1;} + bool operator <(const CARNUMBERCOMBO& sfOther) const + { + return Hash() < sfOther.Hash(); + } +private: + int Hash() const + { + return (iCarNumber<<16) | iSecondaryCarNumber; + } +}; + +// a more civilized lap, constructed from InputLapRaw and sent to the user's ILapReceiver +interface ILap +{ +public: + virtual void Load(V1InputLapRaw* pLap) = 0; + virtual void Load(V2InputLapRaw* pLap) = 0; + virtual bool Load(CSfArtSQLiteDB& db, StartFinish* rgSF, CSfArtSQLiteQuery& line) = 0; + virtual void Free() = 0; // delete the lap + + virtual bool IsValid() const = 0; + virtual int GetStartTime() const = 0; + virtual int GetLapId() const = 0; + virtual float GetTime() const = 0; + virtual const vector GetPoints() const = 0; + virtual const StartFinish* GetSF() const = 0; + virtual wstring GetComment() const = 0; + virtual void SetComment(wstring strComment) const = 0; + + virtual CARNUMBERCOMBO GetCarNumbers() const = 0; +private: +}; +class CMemoryLap : public ILap +{ +public: + CMemoryLap() + { + + } + void Load(V1InputLapRaw* pLap); + void Load(V2InputLapRaw* pLap); + bool Load(CSfArtSQLiteDB& db, StartFinish* rgSF, CSfArtSQLiteQuery& line); + virtual void Free()override {delete this;}; + + bool IsValid() const + { + return dTime < 3600 && dTime > 3.0 && lstPoints.size() > 0; + } + int GetStartTime() const {return iStartTime;} // returns the start time in unix time (seconds since 1970) + int GetLapId() const {return iLapId;} + float GetTime() const {return dTime;} + const vector GetPoints() const {return lstPoints;} + const StartFinish* GetSF() const {return rgSF;} + wstring GetComment() const {return strComment;} + void SetComment(wstring strComment) const override {this->strComment = strComment;} + + virtual CARNUMBERCOMBO GetCarNumbers() const override + { + return sfCarNumbers; + } +private: + vector lstPoints; + StartFinish rgSF[3]; + Vector2D vDir[3]; + float dTime; + int iLapId; + int iStartTime; // seconds since Jan 1 1970 + mutable wstring strComment; + CARNUMBERCOMBO sfCarNumbers; +}; +template +struct TextMatcher +{ + char szToMatch[cToMatch]; + int cMatched; + bool Process(char c) + { + if(cMatched == cToMatch) + { + cMatched = 0; + } + if(szToMatch[cMatched] == c) + { + cMatched++; + } + else + { + cMatched = szToMatch[0] == c; + } + return cMatched == cToMatch; + } + int GetSize() const {return cToMatch;} + void Reset() + { + cMatched = 0; + } + TextMatcher(const char* pbMatch) + { + strcpy(szToMatch,pbMatch); + cMatched = 0; + } +}; + +enum NETSTATUSSTRING +{ + NETSTATUS_STATUS, + NETSTATUS_THISIP, + NETSTATUS_REMOTEIP, + NETSTATUS_DB, // parameter is the file location of the transmitted database file + + NETSTATUS_COUNT, +}; + +struct RACEDATA +{ + RACEDATA() + { + unixtime = 0; + laps = 0; + raceId = -1; + } + wstring strName; + int unixtime; + int laps; + int raceId; +}; + +interface ILapReceiver +{ +public: + // loading from file + virtual bool Init(LPCTSTR lpszSQL) = 0; + virtual bool InitRaceSession(int* iRaceId, LPCTSTR lpszName) = 0; + + // memory management + virtual ILap* AllocateLap(bool fMemory) = 0; + + virtual IDataChannel* AllocateDataChannel() const = 0; + virtual void FreeDataChannel(IDataChannel* pChannel) const = 0; + + // data access + // I chose to access all the laps at once to avoid race condition issues if the network thread updates + // the databank while the UI is displaying it + virtual bool IsActivelyReceiving(int iRaceId) const = 0; // returns whether a given raceId is receiving new laps this session + virtual int GetLastReceivedRaceId() const = 0; // gets the race ID of the last race that received a lap + virtual void GetLastLapTimeStamp(const vector& lstCarNumbers, vector& lstTimeStamps) const = 0; + virtual int GetLapCount(int iRaceId) const = 0; // gets the lap count for a given race + virtual vector GetRaces() = 0; + virtual vector GetLaps(int iRaceId) = 0; + virtual vector GetScoring(int iRaceId) = 0; + virtual const ILap* GetLap(int iLapId) = 0; + virtual const ILap* GetLastLap() = 0; + virtual const IDataChannel* GetDataChannel(int iLapId, DATA_CHANNEL eChannel) const = 0; + virtual set GetAvailableChannels(int iLapId) const = 0; + virtual void GetComments(int iLapId, vector& lstComments) const = 0; + + // modifying data + virtual void AddLap(const ILap* pLap, int iRaceId) = 0; + virtual void AddDataChannel(const IDataChannel* pChannel) = 0; + virtual void Clear() = 0; + virtual void AddComment(int iLapId, LPCTSTR strComment) = 0; + + // status strings + virtual void NotifyDBArrival(LPCTSTR lpszPath) = 0; + virtual void SetNetStatus(NETSTATUSSTRING eString, LPCTSTR szData) = 0; // network man tells us the latest status + virtual LPCTSTR GetNetStatus(NETSTATUSSTRING eString) const = 0; + virtual bool MergeLaps(int m_iRaceId1, int m_iRaceId2) = 0; + virtual bool RenameLaps(TCHAR szName[260], int m_RaceId1) = 0; +// virtual bool m_Button_LiveData(); +}; +/* +// LapSupplier interface - needed so that LapReceiver knows whether or not to collect Live Data, from m_sfLapOpts +interface ILapSupplier { public: - StartFinish() - { - } - StartFinish(float* pPointData) - { - m_pt1.m_v[0] = pPointData[0]; - m_pt1.m_v[1] = pPointData[1]; - m_pt2.m_v[0] = pPointData[2]; - m_pt2.m_v[1] = pPointData[3]; - } - const Vector2D& GetPt1() const {return m_pt1;} - const Vector2D& GetPt2() const {return m_pt2;} -// Vector2D& GetPt1() const {return m_pt1;} -// Vector2D& GetPt2() const {return m_pt2;} -//private: // Made public by KDJ - Vector2D m_pt1; - Vector2D m_pt2; + virtual vector GetLapsToShow() const = 0; // <-- returns which laps you want painted + virtual vector GetAllLaps() const = 0; // <-- returns all the laps + virtual LAPDISPLAYSTYLE GetLapDisplayStyle(int iSupplierId) const = 0; // <-- returns how you want the laps shown: this can be a map or a data plot + virtual DATA_CHANNEL GetXChannel() const = 0; // <-- returns what data channel you want to use for the x-axis + virtual vector GetYChannels() const = 0; // <-- returns what data channels you want to use for the y-axes (can be 1 or more) + virtual const IDataChannel* GetChannel(int iLapId, DATA_CHANNEL eChannel) const = 0; // <-- returns the actual data channel object for a given lap. + virtual FLOATRECT GetAllLapsBounds() const = 0; // <-- returns the x and y bounds for all the laps + + // guide-parameter functions - these configure the background horizontal/vertical lines + virtual float GetGuideStart(DATA_CHANNEL eChannel, float flMin, float flMax) = 0; // <-- returns the position (in the units of whatever data channel you're plotting) of the first line we should draw + virtual float GetGuideStartX(DATA_CHANNEL eChannel, float flMin, float flMax) = 0; // <-- returns the position (in the units of whatever data channel you're plotting) of the first line we should draw + virtual float GetGuideStep(DATA_CHANNEL eChannel, float flMin, float flMax) = 0; // <-- returns the distance between guidelines (in units of whatever data channel you're plotting) + virtual float GetGuideStepX(DATA_CHANNEL eChannel, float flMin, float flMax) = 0; // <-- returns the distance between guidelines (in units of whatever data channel you're plotting) + virtual float GetDataHardcodedMin(DATA_CHANNEL eChannel) const = 0; // <-- returns the absolute lowest value we want to display for a given data channel type + virtual float GetDataHardcodedMax(DATA_CHANNEL eChannel) const = 0; // <-- returns the absolute highest value we want to display for a given data channel type + + // highlighting functions + virtual void SetLapHighlightTime(const CExtendedLap* pLap, int iTimeMs) = 0; // <-- only call if you are a HighlightSource. Sets the time in milliseconds that should be highlighted. + virtual int GetLapHighlightTime(const CExtendedLap* pLap) const = 0; // <-- gets the time in milliseconds that should be highlighted. + virtual bool IsHighlightSource(int iSupplierId) const = 0; // returns whether the caller should be a lap highlighter (calling SetLapHighlightTime) or a lap highlight-receiver (calling GetLapHighlightTime) + + virtual const LAPSUPPLIEROPTIONS& GetDisplayOptions() const = 0; // <-- gets more display options. }; - -struct CARNUMBERCOMBO -{ - int iCarNumber; - int iSecondaryCarNumber; - bool IsOldVersion() const {return iCarNumber == -1 && iSecondaryCarNumber == -1;} - bool operator <(const CARNUMBERCOMBO& sfOther) const - { - return Hash() < sfOther.Hash(); - } -private: - int Hash() const - { - return (iCarNumber<<16) | iSecondaryCarNumber; - } -}; - -// a more civilized lap, constructed from InputLapRaw and sent to the user's ILapReceiver -interface ILap +class CReceiveLapOpts { public: - virtual void Load(V1InputLapRaw* pLap) = 0; - virtual void Load(V2InputLapRaw* pLap) = 0; - virtual bool Load(CSfArtSQLiteDB& db, StartFinish* rgSF, CSfArtSQLiteQuery& line) = 0; - virtual void Free() = 0; // delete the lap - - virtual bool IsValid() const = 0; - virtual int GetStartTime() const = 0; - virtual int GetLapId() const = 0; - virtual float GetTime() const = 0; - virtual const vector GetPoints() const = 0; - virtual const StartFinish* GetSF() const = 0; - virtual wstring GetComment() const = 0; - virtual void SetComment(wstring strComment) const = 0; - - virtual CARNUMBERCOMBO GetCarNumbers() const = 0; -private: + CReceiveLapOpts(ILapSupplier* pLapSupplier); + virtual ~CReceiveLapOpts(); +//private: + ILapSupplier* m_pLapSupplier; }; -class CMemoryLap : public ILap +*/ + +/* +// Pull in the Lap Options information so that data collection can be turned on and off with the button +class CReceiveLapOpts { public: - CMemoryLap() - { - - } - void Load(V1InputLapRaw* pLap); - void Load(V2InputLapRaw* pLap); - bool Load(CSfArtSQLiteDB& db, StartFinish* rgSF, CSfArtSQLiteQuery& line); - virtual void Free()override {delete this;}; - - bool IsValid() const - { - return dTime < 3600 && dTime > 3.0 && lstPoints.size() > 0; - } - int GetStartTime() const {return iStartTime;} // returns the start time in unix time (seconds since 1970) - int GetLapId() const {return iLapId;} - float GetTime() const {return dTime;} - const vector GetPoints() const {return lstPoints;} - const StartFinish* GetSF() const {return rgSF;} - wstring GetComment() const {return strComment;} - void SetComment(wstring strComment) const override {this->strComment = strComment;} - - virtual CARNUMBERCOMBO GetCarNumbers() const override + CReceiveLapOpts(LAPSUPPLIEROPTIONS* q_sfLapOpts) : m_sfLapOpts(q_sfLapOpts) { - return sfCarNumbers; - } -private: - vector lstPoints; - StartFinish rgSF[3]; - Vector2D vDir[3]; - float dTime; - int iLapId; - int iStartTime; // seconds since Jan 1 1970 - mutable wstring strComment; - CARNUMBERCOMBO sfCarNumbers; -}; -template -struct TextMatcher -{ - char szToMatch[cToMatch]; - int cMatched; - bool Process(char c) - { - if(cMatched == cToMatch) - { - cMatched = 0; - } - if(szToMatch[cMatched] == c) - { - cMatched++; - } - else - { - cMatched = szToMatch[0] == c; - } - return cMatched == cToMatch; - } - int GetSize() const {return cToMatch;} - void Reset() - { - cMatched = 0; - } - TextMatcher(const char* pbMatch) - { - strcpy(szToMatch,pbMatch); - cMatched = 0; - } -}; - -enum NETSTATUSSTRING -{ - NETSTATUS_STATUS, - NETSTATUS_THISIP, - NETSTATUS_REMOTEIP, - NETSTATUS_DB, // parameter is the file location of the transmitted database file - - NETSTATUS_COUNT, -}; - -struct RACEDATA -{ - RACEDATA() + }; + // <-- gets more display options. + virtual const LAPSUPPLIEROPTIONS& GetDisplayOptions() const { - unixtime = 0; - laps = 0; - raceId = -1; + return *m_sfLapOpts; } - wstring strName; - int unixtime; - int laps; - int raceId; -}; - -interface ILapReceiver -{ -public: - // loading from file - virtual bool Init(LPCTSTR lpszSQL) = 0; - virtual bool InitRaceSession(int* iRaceId, LPCTSTR lpszName) = 0; - - // memory management - virtual ILap* AllocateLap(bool fMemory) = 0; - - virtual IDataChannel* AllocateDataChannel() const = 0; - virtual void FreeDataChannel(IDataChannel* pChannel) const = 0; - - // data access - // I chose to access all the laps at once to avoid race condition issues if the network thread updates - // the databank while the UI is displaying it - virtual bool IsActivelyReceiving(int iRaceId) const = 0; // returns whether a given raceId is receiving new laps this session - virtual int GetLastReceivedRaceId() const = 0; // gets the race ID of the last race that received a lap - virtual void GetLastLapTimeStamp(const vector& lstCarNumbers, vector& lstTimeStamps) const = 0; - virtual int GetLapCount(int iRaceId) const = 0; // gets the lap count for a given race - virtual vector GetRaces() = 0; - virtual vector GetLaps(int iRaceId) = 0; - virtual vector GetScoring(int iRaceId) = 0; - virtual const ILap* GetLap(int iLapId) = 0; - virtual const IDataChannel* GetDataChannel(int iLapId, DATA_CHANNEL eChannel) const = 0; - virtual set GetAvailableChannels(int iLapId) const = 0; - virtual void GetComments(int iLapId, vector& lstComments) const = 0; - - // modifying data - virtual void AddLap(const ILap* pLap, int iRaceId) = 0; - virtual void AddDataChannel(const IDataChannel* pChannel) = 0; - virtual void Clear() = 0; - virtual void AddComment(int iLapId, LPCTSTR strComment) = 0; - - // status strings - virtual void NotifyDBArrival(LPCTSTR lpszPath) = 0; - virtual void SetNetStatus(NETSTATUSSTRING eString, LPCTSTR szData) = 0; // network man tells us the latest status - virtual LPCTSTR GetNetStatus(NETSTATUSSTRING eString) const = 0; - virtual bool MergeLaps(int m_iRaceId1, int m_iRaceId2) = 0; - virtual bool RenameLaps(TCHAR szName[260], int m_RaceId1) = 0; -}; - -// net-thread entry point. Fills a ILapReceiver from the network -bool ReceiveLaps(int iPort, ILapReceiver* pLaps); - -// fills an ILapReceiver from an SQLite database -void LoadFromSQLite(LPCTSTR lpszSQL, int iRaceId, ILapReceiver* pRecv); +//private: + LAPSUPPLIEROPTIONS* m_sfLapOpts; + bool m_Button_LiveData(); +}; +*/ +// net-thread entry point. Fills a ILapReceiver from the network +bool ReceiveLaps(int iPort, ILapReceiver* pLaps); + +// fills an ILapReceiver from an SQLite database +void LoadFromSQLite(LPCTSTR lpszSQL, int iRaceId, ILapReceiver* pRecv); + +class PassThroughFilter : public CDataChannelFilter +{ +public: + virtual float ApplyTo(float flValue) const override {return flValue;} +}; + +class DoublerFilter : public CDataChannelFilter // for example +{ +public: + virtual float ApplyTo(float flValue) const override {return flValue*2;} +}; + +class SmoothedFilter : public CDataChannelFilter // Smoothes the data channel for display +{ +public: + virtual float ApplyTo(float flValue) const override + { + return flValue; + } +}; + +void fBoxMovingAvg( int n, vector& lstPoints, int w, vector& lstSmoothPts ); + diff --git a/PitsideConsole/PitsideConsole/PitsideConsole.cpp b/PitsideConsole/PitsideConsole/PitsideConsole.cpp index 72f777d..3955e44 100644 --- a/PitsideConsole/PitsideConsole/PitsideConsole.cpp +++ b/PitsideConsole/PitsideConsole/PitsideConsole.cpp @@ -1,38 +1,37 @@ -// PitsideConsole.cpp : Defines the entry point for the console application. -// - -#include "stdafx.h" -#include "pitsideconsole.h" -#include "LapReceiver.h" -#include -#include "AutoCS.h" -#include -#include -//#include "sdl.h" -#include "resource.h" -#include "ArtUI.h" -#include "ArtTools.h" -#include "Windowsx.h" -#include -#include -#include "ArtVector.h" -#include "LapPainter.h" -#include "LapData.h" -#include "DlgMessage.h" -#include "DlgRaceSelect.h" -#include "DlgRaceSelectEdit.h" -#include "DlgPlotSelect.h" // Added by KDJ for Preferences menu -#include "Iphlpapi.h" -#include "ArtSQL/ArtSQLite.h" -#include -#include "DashWare.h" -#include "Multicast.h" -#include "PitsideHTTP.h" -#include "DlgSplash.h" -#include "SQLiteLapDB.h" -#include "UnitTests.h" -#include -#include "Winuser.h" +// PitsideConsole.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "pitsideconsole.h" +#include "LapReceiver.h" +#include +#include "AutoCS.h" +#include +#include +//#include "sdl.h" +#include "resource.h" +#include "ArtUI.h" +#include "ArtTools.h" +#include "Windowsx.h" +#include +#include +#include "ArtVector.h" +#include "LapPainter.h" +#include "LapData.h" +#include "DlgMessage.h" +#include "DlgRaceSelect.h" +#include "DlgRaceSelectEdit.h" +#include "DlgPlotSelect.h" // Added by KDJ for Preferences menu +#include "Iphlpapi.h" +#include "ArtSQL/ArtSQLite.h" +#include +#include "DashWare.h" +#include "Multicast.h" +#include "PitsideHTTP.h" +#include "SQLiteLapDB.h" +#include "UnitTests.h" +#include +#include "Winuser.h" #include "Hyperlinks.h" #include "DlgAbout.h" #include @@ -43,49 +42,50 @@ #include // For Listview sorting routines #include "DlgSelectSessions.h" #include "DlgTimingScoring.h" -#include "DlgTractionCircle.h" +#include "LapReceiver.h" + +//#pragma comment(lib,"sdl.lib") +using namespace std; + +ILapReceiver* g_pLapDB = NULL; + +SimpleHTTPServer* g_pHTTPServer = NULL; + +struct COMPUTERDESC +{ +public: + char szDesc[100]; // computer name +}; + +class MCResponder : public MulticastResponseGenerator +{ +public: + virtual void GetResponse(const char* pbReceived, int cbReceived, char** ppbResponse, int* pcbResponse) override + { + COMPUTERDESC* pResp = new COMPUTERDESC(); + + TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH +1] = L""; + DWORD cchComputerName = MAX_COMPUTERNAME_LENGTH +1; + BOOL fSuccess = GetComputerName(szComputerName, &cchComputerName); + + if(fSuccess) + { + sprintf(pResp->szDesc,"%S",szComputerName); + } + else + { + sprintf(pResp->szDesc,"Unknown Computer"); + } + *ppbResponse = (char*)pResp; + *pcbResponse = sizeof(*pResp); + } +}; + +bool CLap_SortByTime(const ILap* p1, const ILap* p2) +{ + return p1->GetStartTime() < p2->GetStartTime(); +} -//#pragma comment(lib,"sdl.lib") -using namespace std; - -ILapReceiver* g_pLapDB = NULL; - -SimpleHTTPServer* g_pHTTPServer = NULL; - -struct COMPUTERDESC -{ -public: - char szDesc[100]; // computer name -}; - -class MCResponder : public MulticastResponseGenerator -{ -public: - virtual void GetResponse(const char* pbReceived, int cbReceived, char** ppbResponse, int* pcbResponse) override - { - COMPUTERDESC* pResp = new COMPUTERDESC(); - - TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH +1] = L""; - DWORD cchComputerName = MAX_COMPUTERNAME_LENGTH +1; - BOOL fSuccess = GetComputerName(szComputerName, &cchComputerName); - - if(fSuccess) - { - sprintf(pResp->szDesc,"%S",szComputerName); - } - else - { - sprintf(pResp->szDesc,"Unknown Computer"); - } - *ppbResponse = (char*)pResp; - *pcbResponse = sizeof(*pResp); - } -}; - -bool CLap_SortByTime(const ILap* p1, const ILap* p2) -{ - return p1->GetStartTime() < p2->GetStartTime(); -} // this object takes the laps received on the net thread, stores them, and notifies the UI of the new laps class CLapReceiver : public ILapReceiver { @@ -243,56 +243,58 @@ class CLapReceiver : public ILapReceiver TCHAR szLastNetStatus[NETSTATUS_COUNT][200]; mutable ManagedCS m_cs; }; - -IUI* g_pUI = NULL; - -INT_PTR CALLBACK DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if(g_pUI) - { - return g_pUI->DlgProc(hWnd,uMsg,wParam,lParam); - } - return FALSE; -} - -#define WM_NOTIFYUPDATE (WM_USER+0x1) -#define WM_UPDATEUI (WM_USER+0x2) - -bool CExtendedLap_SortByTime(const CExtendedLap* p1, const CExtendedLap* p2) -{ - return p1->GetLap()->GetStartTime() < p2->GetLap()->GetStartTime(); -} + +IUI* g_pUI = NULL; + +INT_PTR CALLBACK DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if(g_pUI) + { + return g_pUI->DlgProc(hWnd,uMsg,wParam,lParam); + } + return FALSE; +} + +#define WM_NOTIFYUPDATE (WM_USER+0x1) +#define WM_UPDATEUI (WM_USER+0x2) + +bool CExtendedLap_SortByTime(const CExtendedLap* p1, const CExtendedLap* p2) +{ + return p1->GetLap()->GetStartTime() < p2->GetLap()->GetStartTime(); +} bool CExtendedLap_SortByLapTime(const CExtendedLap* p1, const CExtendedLap* p2) { return p1->GetLap()->GetTime() < p2->GetLap()->GetTime(); // GetTime() or whatever the function is that gets lap time } - -class CMainUI : public IUI,public ILapSupplier -{ -public: - CMainUI() - : m_sfLapPainter(/*static_cast(this), */static_cast(this),SUPPLIERID_MAINDISPLAY), - m_sfSubDisplay(/*static_cast(this), */static_cast(this),SUPPLIERID_SUBDISPLAY), - m_sfTractionDisplay(/*static_cast(this), */static_cast(this),SUPPLIERID_TRACTIONCIRCLEDISPLAY), - m_eLapDisplayStyle(LAPDISPLAYSTYLE_PLOT), // Make data plot the default initial view - m_fShowTractionCircle(false), - m_fShowBests(false), - m_fShowDriverBests(false), - m_fShowReferenceLap(true), - m_pReferenceLap(NULL), - m_eXChannel(DATA_CHANNEL_DISTANCE), - m_fdwUpdateNeeded(0), - m_flShiftX(0), - m_flShiftY(0) - { - m_iRaceId[0] = 0; - m_lstYChannels.push_back(DATA_CHANNEL_VELOCITY); - m_szCommentText[0] = '\0'; - m_szMessageStatus[0] = '\0'; - SetupMulticast(); - } - DWORD tmNow, tmLast; // Variables for setting up receive time / live car position - + +class CMainUI : public IUI,public ILapSupplier +{ +public: + CMainUI() + : m_sfLapPainter(static_cast(this),SUPPLIERID_MAINDISPLAY), + m_sfSubDisplay(static_cast(this),SUPPLIERID_SUBDISPLAY), +// m_sfSubWindow(static_cast(this),SUPPLIERID_SUBWINDOW), + m_sfTractionDisplay(static_cast(this),SUPPLIERID_TRACTIONCIRCLEDISPLAY), + m_eLapDisplayStyle(LAPDISPLAYSTYLE_PLOT), // Make data plot the default initial view + m_fShowTractionCircle(false), + m_fSmooth(false), + m_fShowBests(false), + m_fShowDriverBests(false), + m_fShowReferenceLap(true), + m_pReferenceLap(NULL), + m_eXChannel(DATA_CHANNEL_DISTANCE), + m_fdwUpdateNeeded(0), + m_flShiftX(0), + m_flShiftY(0) + { + m_iRaceId[0] = 0; + m_lstYChannels.push_back(DATA_CHANNEL_VELOCITY); + m_szCommentText[0] = '\0'; + m_szMessageStatus[0] = '\0'; + SetupMulticast(); + } + DWORD tmNow, tmLast; // Variables for setting up receive time / live car position + ////////////////////////////////////////////////////////////////////////////////// RECT rect; HBITMAP hBitmap; @@ -303,23 +305,23 @@ class CMainUI : public IUI,public ILapSupplier HPALETTE hpal; int cxsize, cxpage; int cysize, cypage; -////////////////////////////////////////////////////////////////////////////////// - -void SetRaceId(int iRaceId[50]) - { - for (int z = 0; z < 50; z++) - { - m_iRaceId[z] = iRaceId[z]; // Load all of the race sessions chosen - } - } - void NotifyChange(WPARAM wParam, LPARAM lParam) override - { - if(m_hWnd != NULL) - { - PostMessage(m_hWnd,WM_NOTIFYUPDATE,wParam,(LPARAM)lParam); - } - } - +////////////////////////////////////////////////////////////////////////////////// + +void SetRaceId(int iRaceId[50]) + { + for (int z = 0; z < 50; z++) + { + m_iRaceId[z] = iRaceId[z]; // Load all of the race sessions chosen + } + } + void NotifyChange(WPARAM wParam, LPARAM lParam) override + { + if(m_hWnd != NULL) + { + PostMessage(m_hWnd,WM_NOTIFYUPDATE,wParam,(LPARAM)lParam); + } + } + int str_ends_with(const TCHAR * str, const TCHAR * suffix) { if( str == NULL || suffix == NULL ) @@ -333,9 +335,9 @@ void SetRaceId(int iRaceId[50]) return 0 == wcsncmp( str + str_len - suffix_len, suffix, suffix_len ); } - LAPSUPPLIEROPTIONS m_sfLapOpts; - TCHAR m_szPath[MAX_PATH]; - + LAPSUPPLIEROPTIONS m_sfLapOpts; + TCHAR m_szPath[MAX_PATH]; + ///////////////////////////////////////////////////////////////////////////////// // Functions for enabling Printing of OpenGL graphs HDC GetPrinterDC (HWND Hwnd) @@ -488,2512 +490,4121 @@ LPDEVMODE GetLandscapeDevMode(HWND hWnd, wchar_t *pDevice, HANDLE hPrinter) // Return the modified DevMode structure. return pDevMode; } -/////////////////////////////////////////////////////////////////////////////////////// - - LRESULT DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - if(m_sfLapPainter.HandleMessage(hWnd,uMsg,wParam,lParam)) - { - return 0; - } - - // Update and show Current Lap Time - TCHAR szTemp[512], szLap[512]; - HWND hWndIp = GetDlgItem(m_hWnd, IDC_LIVELAPTIME); - ::FormatTimeMinutesSecondsMs((float)(timeGetTime() - tmLast) / 1000, szLap, NUMCHARS(szLap) ); - swprintf(szLap, _tcslen(szLap) - 2, L"%s", szLap); // Remove the fractional time - swprintf(szTemp, NUMCHARS(szTemp), L"Current Lap: %s", szLap); - SendMessage(hWndIp, WM_SETTEXT, 0, (LPARAM)szTemp); - - switch(uMsg) - { - case WM_INITDIALOG: - { - m_hWnd = hWnd; - - { - vector lstCols; - vector lstWidths; - CExtendedLap::GetStringHeadersXAxis(lstCols,lstWidths); - m_sfXAxis.Init(GetDlgItem(m_hWnd, IDC_XAXIS),lstCols,lstWidths); - } - { - vector lstCols; - vector lstWidths; - CExtendedLap::GetStringHeadersYAxis(lstCols,lstWidths); - m_sfYAxis.Init(GetDlgItem(m_hWnd, IDC_YAXIS),lstCols,lstWidths); - } - { - vector lstCols; - vector lstWidths; - CExtendedLap::GetStringHeaders(lstCols,lstWidths); - m_sfLapList.Init(GetDlgItem(hWnd, IDC_LAPS), lstCols,lstWidths); - } - m_sfLapPainter.Init(GetDlgItem(hWnd,IDC_DISPLAY)); - m_sfSubDisplay.Init(GetDlgItem(hWnd,IDC_SUBDISPLAY)); - m_sfTractionDisplay.Init(GetDlgItem(hWnd,IDC_TRACTIONCIRCLEMAP)); - - set setAvailable; - InitAxes(setAvailable); - LoadLaps(::g_pLapDB); - UpdateUI(UPDATE_ALL); - InitBaseWindowPos(); - - tmLast = timeGetTime(); // Initialize time lap was received - return 0; - } - case WM_CLOSE: - EndDialog(hWnd,0); - return 0; - case WM_MOUSEWHEEL: - { - short iDist = HIWORD(wParam); - m_sfLapOpts.iZoomLevels += (iDist/WHEEL_DELTA); - UpdateUI(UPDATE_MAP); - return 0; - } - case WM_MOUSEMOVE: - { - const int INVALID_MOUSEPOS = 0x80000000; - static int lastX = INVALID_MOUSEPOS; - static int lastY = INVALID_MOUSEPOS; - const int x = LOWORD(lParam); - const int y = HIWORD(lParam); - const int moveX = lastX == INVALID_MOUSEPOS ? 0 : x - lastX; - const int moveY = lastY == INVALID_MOUSEPOS ? 0 : y - lastY; - lastX = x; - lastY = y; - - if(IS_FLAG_SET(wParam, MK_LBUTTON)) - { - // they're dragging! - m_sfLapOpts.flWindowShiftX += moveX; - m_sfLapOpts.flWindowShiftY -= moveY; - } - UpdateUI(UPDATE_MAP); - return 0; - } - case WM_LBUTTONDOWN: - { - const int x = LOWORD(lParam); - const int y = HIWORD(lParam); - // figure out if we should put focus on the main map - RECT rcMap; - HWND hWndMap = GetDlgItem(this->m_hWnd,IDC_DISPLAY); - GetClientRect(hWndMap,&rcMap); - if(x >= rcMap.left && x < rcMap.right && y >= rcMap.top && y < rcMap.bottom) - { - SetFocus(hWndMap); - return TRUE; - } - return FALSE; - } - case WM_LBUTTONDBLCLK: - { - const int x = LOWORD(lParam); - const int y = HIWORD(lParam); - // figure out if we should put focus on the main map - RECT rcMap; - HWND hWndMap = GetDlgItem(this->m_hWnd,IDC_DISPLAY); - GetClientRect(hWndMap,&rcMap); - if(x >= rcMap.left && x < rcMap.right && y >= rcMap.top && y < rcMap.bottom) - { - SetFocus(hWndMap); - return TRUE; - } - // Now display the closest values on the map. -/* const float flDataX = MagicDeterminingFunction(sfLapOpts, fHighlightXAxis); // this part could be hard... - vector lstLaps = GetLapsToShow(); - if(lstLaps.size() >= 2) // don't show anything if we've got multiple laps selected - { - set setChannels = lstLaps[0]->GetAvailableChannels(); - stringstream ss; - for(set::const_iterator i = setChannels.begin(); i != setChannels.end(); i++) +/////////////////////////////////////////////////////////////////////////////////// +// Tentative code for Custom Draw of ListViews implementation + LRESULT ProcessCustomDraw (LPARAM lParam, WPARAM wParam, INT i_Color) + { + LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam; + + switch(lplvcd->nmcd.dwDrawStage) + { + case CDDS_PREPAINT : // Before the paint cycle begins + return CDRF_NOTIFYITEMDRAW; // Request notifications for individual listview items + + case CDDS_ITEMPREPAINT: // Before an item is drawn + { + return CDRF_NOTIFYSUBITEMDRAW; // Request notifications for individual listview SubItems + } + break; + + case CDDS_SUBITEM | CDDS_ITEMPREPAINT: // Before a subitem is drawn { - const IDataChannel* pChannel = GetChannel(*i); - if(pChannel) + // switch(lplvcd->iSubItem) + switch(i_Color) { - const float flValue = pChannel->GetValue(flDataX); - TCHAR szName[100]; - GetDataChannelName(*i,szName,NUMCHARS(szName)); - char szValue[100]; - GetChannelString(*i, m_sfLapOpts.eUnitPreference, flValue, szValue, NUMCHARS(szValue)); - ss<clrText = RGB(0,0,0); + lplvcd->clrTextBk = RGB(255,255,255); + return CDRF_NEWFONT; + } + break; + + case 1: + { + // Red background, white letters + lplvcd->clrText = RGB(255,255,255); + lplvcd->clrTextBk = RGB(240,55,23); + return CDRF_NEWFONT; + } + break; + + case 2: + { + // Green background, black letters + lplvcd->clrText = RGB(0,0,0); + lplvcd->clrTextBk = RGB(155,255,80); + return CDRF_NEWFONT; + } + break; + case 3: + { + // Blue background, white letters + lplvcd->clrText = RGB(255,255,255); + lplvcd->clrTextBk = RGB(20,20,220); + return CDRF_NEWFONT; + } + break; + case 4: + { + // Black letters, Light Grey background (Default) + lplvcd->clrText = RGB(0,0,0); + lplvcd->clrTextBk = RGB(240,240,255); + return CDRF_NEWFONT; + } + break; } } - MessageBox(NULL, ss.c_str(), NULL, NULL); + } + return CDRF_DODEFAULT; + } - } -*/ return TRUE; - } - case WM_NOTIFY: - { - NMHDR* notifyHeader = (NMHDR*)lParam; - switch(wParam) - { - case IDC_LAPS: - switch(notifyHeader->code) - { - case LVN_ITEMCHANGED: - { - NMITEMACTIVATE* pDetails = (NMITEMACTIVATE*)notifyHeader; - if(pDetails->iItem >= 0) - { - UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - } - return TRUE; - } - case LVN_COLUMNCLICK: - { - LPNMLISTVIEW pLVInfo = (LPNMLISTVIEW)lParam; - // User clicked the column header, let's re-sort the list - if (pLVInfo->iSubItem == SORTSTYLE_BYTIMEOFRACE && m_sfLapOpts.eSortPreference != SORTSTYLE_BYTIMEOFRACE) - { - m_sfLapOpts.eSortPreference = SORTSTYLE_BYTIMEOFRACE; - UpdateUI(UPDATE_MENU | UPDATE_DASHBOARD | UPDATE_LIST); - } - else if (pLVInfo->iSubItem == SORTSTYLE_BYLAPTIME && m_sfLapOpts.eSortPreference != SORTSTYLE_BYLAPTIME) - { - m_sfLapOpts.eSortPreference = SORTSTYLE_BYLAPTIME; - UpdateUI(UPDATE_MENU | UPDATE_DASHBOARD | UPDATE_LIST); - } - } - } - break; - case IDC_XAXIS: - switch(notifyHeader->code) - { - case LVN_ITEMCHANGED: - const set sel = m_sfXAxis.GetSelectedItemsData(); - if(sel.size() == 1) - { - m_eXChannel = (DATA_CHANNEL)*sel.begin(); - NMITEMACTIVATE* pDetails = (NMITEMACTIVATE*)notifyHeader; - if(pDetails->iItem >= 0) - { - UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - } - } - return TRUE; - } - break; - case IDC_YAXIS: - switch(notifyHeader->code) - { - case LVN_ITEMCHANGED: - const set sel = m_sfYAxis.GetSelectedItemsData(); - if(sel.size() >= 1) - { - m_lstYChannels.clear(); - for(set::iterator i = sel.begin(); i != sel.end(); i++) - { - m_lstYChannels.push_back((DATA_CHANNEL)*i); - } - NMITEMACTIVATE* pDetails = (NMITEMACTIVATE*)notifyHeader; - if(pDetails->iItem >= 0) - { - UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - } - } - return TRUE; - } - break; - } // end switch on wParam - } // end body of case WM_NOTIFY - case WM_COMMAND: - { - switch(LOWORD(wParam)) // find out the control ID - { - case IDC_SENDMESSAGE: - { - MESSAGEDLG_RESULT sfResult; - CMessageDlg dlgMessage(&sfResult); - - HWND hWndButton = GetDlgItem(this->m_hWnd,IDC_SENDMESSAGE); - EnableWindow(hWndButton,FALSE); - ArtShowDialog(&dlgMessage); - EnableWindow(hWndButton,TRUE); - LPCTSTR lpsz = g_pLapDB->GetNetStatus(NETSTATUS_REMOTEIP); - sprintf(sfResult.szIP, "%S", lpsz); - - if(!sfResult.fCancelled) - { - // now that we're done, we should have a result! - SendMsg(sfResult, this); - } - return TRUE; - } - case IDOK: - { - return TRUE; - } - case ID_OPTIONS_KMH: - { - m_sfLapOpts.eUnitPreference = UNIT_PREFERENCE_KMH; - UpdateUI(UPDATE_MAP | UPDATE_MENU); - return TRUE; - } - case ID_OPTIONS_MPH: - { - m_sfLapOpts.eUnitPreference = UNIT_PREFERENCE_MPH; - UpdateUI(UPDATE_MAP | UPDATE_MENU); - return TRUE; - } - case ID_OPTIONS_MS: - { - m_sfLapOpts.eUnitPreference = UNIT_PREFERENCE_MS; - UpdateUI(UPDATE_MAP | UPDATE_MENU); - return TRUE; - } - case ID_OPTIONS_SHOWBESTS: - { - m_fShowBests = !m_fShowBests; - UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - return TRUE; - } - case ID_OPTIONS_SHOWREFERENCELAP: - { - m_fShowReferenceLap = !m_fShowReferenceLap; - UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - return TRUE; - } - case ID_OPTIONS_DRAWLINES: - { - m_sfLapOpts.fDrawLines = !m_sfLapOpts.fDrawLines; - UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD); - return TRUE; - } - case ID_OPTIONS_BACKGROUND: - { - m_sfLapOpts.fColorScheme = !m_sfLapOpts.fColorScheme; - UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD); - return TRUE; - } - case ID_OPTIONS_IOIO5VSCALE: - { - m_sfLapOpts.fIOIOHardcoded = !m_sfLapOpts.fIOIOHardcoded; - UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD); - return TRUE; - } - case ID_OPTIONS_SHOWDRIVERBESTS: - { - m_fShowDriverBests = !m_fShowDriverBests; - UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - return TRUE; - } - case ID_DATA_SWITCHSESSION: - { - RACESELECT_RESULT sfResult; - - // Zero out the Race ID's before selecting them - for (int z = 0; z < 50; z++) - { - m_iRaceId[z] = -1; - sfResult.iRaceId[z] = -1; - } - - CRaceSelectDlg dlgRace(g_pLapDB, &sfResult); - ArtShowDialog(&dlgRace); - - if(!sfResult.fCancelled) - { - for (int z = 0; z < 50; z++) - { - m_iRaceId[z] = sfResult.iRaceId[z]; // Load all of the race sessions chosen - } - ClearUILaps(); - LoadLaps(g_pLapDB); - UpdateUI(UPDATE_ALL); - // Just loaded a new session. Let's reset the timer - tmLast = timeGetTime(); // Save last time lap was received - } - return TRUE; - } - case ID_DATA_EDITSESSION: - { - RACESELECTEDIT_RESULT sfResult; - CRaceSelectEditDlg dlgRace(g_pLapDB, &sfResult); - ArtShowDialog(&dlgRace); - - if(!sfResult.fCancelled) - { - m_iRaceId[0] = sfResult.iRaceId; - ClearUILaps(); - LoadLaps(g_pLapDB); - UpdateUI(UPDATE_ALL); - } - return TRUE; - } - case ID_OPTIONS_PLOTPREFS: - { - PLOTSELECT_RESULT sfResult; - CPlotSelectDlg dlgPlot(g_pLapDB, &sfResult, m_iRaceId[0], &m_sfLapOpts); - ArtShowDialog(&dlgPlot); - - UpdateUI(UPDATE_ALL | UPDATE_VALUES); - - return TRUE; - } - case ID_OPTIONS_SETSPLITS: - { - SETSPLITSDLG_RESULT sfResult; - CSetSplitsDlg dlgSetSplits(g_pLapDB, m_pReferenceLap, &sfResult, m_iRaceId[0], &m_sfLapOpts); - ArtShowDialog(&dlgSetSplits); - - static HWND ShowSplitsHandle; - const int cSectors = 9; // Maximum numbers of Split Times - const int MaxLaps = 7; // Maximum number of laps to display - if (!IsWindow(ShowSplitsHandle) && m_sfLapOpts.fDrawSplitPoints) - { - // Create non-modal dialog to display the sector times window if DrawSplitPoints is TRUE - HWND hwndSplits = NULL; // Window handle of non-modal dialog box - DLGPROC ShowSplits = NULL; - if (!IsWindow(hwndSplits)) - { - hwndSplits = CreateDialog(NULL, MAKEINTRESOURCE (IDD_SHOWSECTORS), hWnd, ShowSplits); - // Let's get the handles for all display controls in this window - for (int y = 0; y < MaxLaps; y++) - { - m_sfLapOpts.hWndLap[y] = GetDlgItem(hwndSplits, IDC_SHOW_LAP0 + y); - } - ShowSplitsHandle = hwndSplits; // Tracker for handle address - ShowWindow(hwndSplits, SW_SHOW); - } - } - else if (!m_sfLapOpts.fDrawSplitPoints) - { - EndDialog(ShowSplitsHandle, 0); - ShowSplitsHandle = NULL; - } - if(!sfResult.fCancelled) - { - UpdateUI(UPDATE_ALL | UPDATE_VALUES); - return TRUE; - } - return TRUE; - } - case ID_HELP_SHOWHELP: - { - ShowHelp(hWnd); - return TRUE; - } - case ID_HELP_SHOWWFLHELP: - { - ShowWFLHelp(hWnd); - return TRUE; - } - case ID_HELP_IPS: - { - ShowNetInfo(); - return TRUE; - } - case ID_HELP_ABOUT: - { - ABOUT_RESULT sfResult; - CAboutDlg dlgAbout(&sfResult); - ArtShowDialog(&dlgAbout); - UpdateUI(UPDATE_ALL); - return TRUE; - } - case ID_OPTIONS_TRACTIONCIRCLE: - { - m_fShowTractionCircle = !m_fShowTractionCircle; - m_sfLapOpts.bTractionCircle = m_fShowTractionCircle; -/* TRACTIONCIRCLEDLG_RESULT sfResult; -// CTractionCircleDlg dlgTractionCircle(g_pLapDB, m_pReferenceLap, &sfResult, m_iRaceId[0], &m_sfLapOpts); -// ArtShowDialog(&dlgTractionCircle); - - if(!sfResult.fCancelled) - { - UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); -// UpdateUI(UPDATE_ALL | UPDATE_VALUES); - return TRUE; - } -*/ UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_TRACTIONCIRCLE); - return TRUE; - } - // Nested loop for the following functions - case ID_EDIT_COPY: - { - // Option is not working and causes crashes right now, so disable it - return TRUE; - } - case IDM_PRINT_BM: - case IDM_SAVE_BM: - { - int SaveFlag = false, PrintFlag = false; - // Set flag to sending image to Clipboard, if requested by user - if (LOWORD(wParam) == IDM_SAVE_BM) - SaveFlag = true; - if (LOWORD(wParam) == IDM_PRINT_BM) - PrintFlag = true; - - // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF - // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO - // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A - // PARTICULAR PURPOSE. - // - // Copyright (c) Microsoft Corporation. All rights reserved +///////////////////////////////////////////////////////////////////////////////////////// - // - // FUNCTION: CaptureAnImage(HWND hWnd) - // - // PURPOSE: Captures a screenshot into a window and then saves it in a .bmp file. - // - // COMMENTS: - // - // Note: This sample will attempt to create a file called captureqwsx.bmp - // +/////////////////////////////////////////////////////////////////////////////////////// + HWND hWnd_AllData; // AllData window control handle + HWND AD_hWnd; // AllData listview control handle + LVITEM p_ADlvi; // Listview global pointer for Hot Laps + HWND hWndShowSplits; // Show Sectors window control handle + HWND HC_ShowSplits; // Handle to the Splits listview control +// HWND sub_hWnd; // Handle to the SubWindow, to get to the SubDisplay control + BOOL b_GreyColor; // Switch for painting listviews with alternating lines of color + INT i_SubItemBest, i_SubItemWorst; + BOOL b_Button_LiveData; - HDC hdcSource; - HDC hdcWindow; - HDC hdcMemDC = NULL; - HBITMAP hbmSource = NULL; - BITMAP bmpSource; + LRESULT DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + if(m_sfLapPainter.HandleMessage(hWnd,uMsg,wParam,lParam)) + { + return 0; + } - // Retrieve the handle to a display device context for the client area of the window. - hdcSource = GetDC(NULL); - hdcWindow = GetDC(hWnd); + // Update and show Current Lap Time + TCHAR szTemp[512], szLap[512]; + HWND hWndIp = GetDlgItem(m_hWnd, IDC_LIVELAPTIME); + static WINDOWPLACEMENT w_AllDataWindow; // Save the location for the AllData display window + static WINDOWPLACEMENT w_SectorTimesWindow; // Save the location for the Sector Times display window + ::FormatTimeMinutesSecondsMs((float)(timeGetTime() - tmLast) / 1000, szLap, NUMCHARS(szLap) ); + swprintf(szLap, _tcslen(szLap) - 2, L"%s", szLap); // Remove the fractional time + swprintf(szTemp, NUMCHARS(szTemp), L"Current Lap: %s", szLap); // Final string to show current lap time + SendMessage(hWndIp, WM_SETTEXT, 0, (LPARAM)szTemp); - // Create a compatible DC which is used in a BitBlt from the window DC - hdcMemDC = CreateCompatibleDC(hdcWindow); + switch(uMsg) + { + case WM_INITDIALOG: + { + m_hWnd = hWnd; + hWndShowSplits = NULL; + { + vector lstCols; + vector lstWidths; + CExtendedLap::GetStringHeadersXAxis(lstCols,lstWidths); + m_sfXAxis.Init(GetDlgItem(m_hWnd, IDC_XAXIS),lstCols,lstWidths); + CExtendedLap::SetDistance(m_sfLapOpts.bXAxis_KM); // Set the X Axis as read from SETTINGS.TXT file + } + { + vector lstCols; + vector lstWidths; + CExtendedLap::GetStringHeadersYAxis(lstCols,lstWidths); + m_sfYAxis.Init2(GetDlgItem(m_hWnd, IDC_YAXIS),lstCols,lstWidths); + } + { + vector lstCols; + vector lstWidths; + CExtendedLap::GetStringHeadersDataValues(lstCols,lstWidths); + m_sfLapList.Init(GetDlgItem(m_hWnd, IDC_DATAVALUES), lstCols,lstWidths); + } + { + vector lstCols; + vector lstWidths; + CExtendedLap::GetStringHeaders(lstCols,lstWidths); + m_sfLapList.Init(GetDlgItem(m_hWnd, IDC_LAPS), lstCols,lstWidths); + } + m_sfLapPainter.Init(GetDlgItem(hWnd,IDC_DISPLAY)); +// ArtShowDialog(s_pUI); +// sub_hWnd = GetDlgItem(m_hWnd,IDD_DLGSUBDISPLAY); +// sub_hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, L"SubDisplay", L"SubDisplay", WS_POPUP | WS_SYSMENU | WS_THICKFRAME | WS_CAPTION, 586, 0, 87, 63, m_hWnd, NULL, GetModuleHandle(0), NULL); +// m_sfSubDisplay.Init(GetDlgItem(sub_hWnd,IDC_SUBDISPLAY)); + m_sfSubDisplay.Init(GetDlgItem(m_hWnd,IDC_SUBDISPLAY)); + m_sfTractionDisplay.Init(GetDlgItem(m_hWnd,IDC_TRACTIONCIRCLEMAP)); - if(!hdcMemDC) + LoadLaps(g_pLapDB); + if (m_sfLapOpts.LapId != 0 && m_mapLaps.size() > 0) // Reference lap needs to be loaded. Identify which one it is and set it + { + for(map::iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) + { + if(i->second->GetLap()->GetLapId() == m_sfLapOpts.LapId) + { + m_pReferenceLap = i->second; // Set the Reference lap to this lap + } + } + m_pReferenceLap->ComputeDistances(NULL, g_pLapDB); // Now recompute distances, based upon this Reference Lap + for(map::iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) + { + if(i->second != m_pReferenceLap) { - MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK); - break; + i->second->ComputeDistances(m_pReferenceLap, g_pLapDB); // tell this lap to recompute using pLap as the reference lap } - - // Get the client area for size calculation - RECT rcClient; - // Get the windows coordinates for the Window, hWnd - ::GetWindowRect (hWnd,&rcClient); - // Get the dimensions of the target image handle, hWnd - RECT rc; - ::GetWindowRect (hWnd,&rc); - //This is the best stretch mode - SetStretchBltMode(hdcWindow,HALFTONE); + } + } - //The source DC is the current window and the destination DC is the current window (HWND) - if(!StretchBlt(hdcWindow, - 0,0, - rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, - hdcSource, - rc.left+8, rc.top+50, // Adjustments to remove menu duplicate - rc.right-rc.left, rc.bottom-rc.top, - SRCCOPY)) - { - MessageBox(hWnd, L"StretchBlt has failed",L"Failed", MB_OK); - break; - } - - // Create a compatible bitmap from the Window DC - hbmSource = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top); - - if(!hbmSource) - { - MessageBox(hWnd, L"CreateCompatibleBitmap Failed",L"Failed", MB_OK); - break; - } + + set setAvailable; + InitAxes(setAvailable); + LoadLaps(::g_pLapDB); + UpdateUI(UPDATE_ALL); + InitBaseWindowPos(); - // Select the compatible bitmap into the compatible memory DC. - SelectObject(hdcMemDC,hbmSource); - - // Bit block transfer into our compatible memory DC. - if(!BitBlt(hdcMemDC, - 0,0, - rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, - hdcSource, - rcClient.left,rcClient.top, - SRCCOPY)) + tmLast = timeGetTime(); // Initialize time lap was received + + // Find all of the Names of the selected Race Sessions for addition to title bar + vector lstRaces = g_pLapDB->GetRaces(); + TCHAR lstSessions[MAX_PATH] = {NULL}; + for(int x = 0;x < lstRaces.size(); x++) + { + for (int z = 0; z < 50; z++) + { + if ( m_iRaceId[z] == lstRaces[x].raceId ) { - MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK); + _snwprintf(lstSessions, NUMCHARS(lstSessions), L"%s | %s", lstSessions, lstRaces[x].strName.c_str()); break; } + } + } + + TCHAR szTemp[MAX_PATH] = {NULL}; + _snwprintf(szTemp, NUMCHARS(szTemp), L"Pitside - %s%s", m_szPath, lstSessions); + SetWindowText(m_hWnd, szTemp ); // Change the title bar to show the file name and Session(s) opened - // Get the BITMAP from the HBITMAP - GetObject(hbmSource,sizeof(BITMAP),&bmpSource); - - BITMAPFILEHEADER bmfHeader = {0}; - BITMAPINFOHEADER bi = {0}; - - bi.biSize = sizeof(BITMAPINFOHEADER); - bi.biWidth = bmpSource.bmWidth; - bi.biHeight = bmpSource.bmHeight; - bi.biPlanes = 1; - bi.biBitCount = 32; - bi.biCompression = BI_RGB; - bi.biSizeImage = 0; - bi.biXPelsPerMeter = 0; - bi.biYPelsPerMeter = 0; - bi.biClrUsed = 0; - bi.biClrImportant = 0; + if (m_sfLapOpts.fDrawSplitPoints == true) // Initialize the Sector Times window + { + // Create non-modal dialog to display the sector times window if DrawSplitPoints is TRUE + DLGPROC ShowSplits = NULL; + // Create the window for displaying sector times for the selected laps + INITCOMMONCONTROLSEX InitCtrlEx; + InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitCtrlEx.dwICC = ICC_PROGRESS_CLASS; + InitCommonControlsEx(&InitCtrlEx); + hWndShowSplits = CreateDialog(NULL, MAKEINTRESOURCE (IDD_SHOWSECTORS), hWnd, (DLGPROC)ShowSplits); // Create resource + HC_ShowSplits = GetDlgItem(hWndShowSplits, IDC_SHOW_SECTORS); // Let's get the handle for the display control in this window + SetWindowPlacement(hWndShowSplits, &w_SectorTimesWindow); // Maintains the location of the Sector Times window - DWORD dwBmpSize = ((bmpSource.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpSource.bmHeight; + // Set up the Sector Times list box columns + vector lstCols; + vector lstWidths; + lstCols.push_back(L"Lap ID"); + lstCols.push_back(L"1"); + lstCols.push_back(L"2"); + lstCols.push_back(L"3"); + lstCols.push_back(L"4"); + lstCols.push_back(L"5"); + lstCols.push_back(L"6"); + lstCols.push_back(L"7"); + lstCols.push_back(L"8"); + lstCols.push_back(L"9"); + lstWidths.push_back(195); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); - // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that - // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc - // have greater overhead than HeapAlloc. - HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); - char *lpbitmap = (char *)GlobalLock(hDIB); + m_sfListBox.Init(HC_ShowSplits,lstCols,lstWidths); // Initialize and show the Sector Splits window + ShowWindow(hWndShowSplits, SW_SHOW); + } - // Gets the "bits" from the bitmap and copies them into a buffer - // which is pointed to by lpbitmap. - GetDIBits(hdcWindow, hbmSource, 0, - (UINT)bmpSource.bmHeight, - lpbitmap, - (BITMAPINFO *)&bi, DIB_RGB_COLORS); + return 0; + } + case WM_CLOSE: + { + DestroyWindow(hWnd); + EndDialog(hWnd,0); + return 0; + } + case WM_MOUSEWHEEL: + { + short iDist = HIWORD(wParam); + m_sfLapOpts.iZoomLevels += (iDist/WHEEL_DELTA); + UpdateUI(UPDATE_MAP); + return 0; + } + case WM_MOUSEMOVE: + { + const int INVALID_MOUSEPOS = 0x80000000; + static int lastX = INVALID_MOUSEPOS; + static int lastY = INVALID_MOUSEPOS; + const int x = LOWORD(lParam); + const int y = HIWORD(lParam); + const int moveX = lastX == INVALID_MOUSEPOS ? 0 : x - lastX; + const int moveY = lastY == INVALID_MOUSEPOS ? 0 : y - lastY; + lastX = x; + lastY = y; - // If request is to save or print an image file, request name and save it. - if (SaveFlag || PrintFlag) - { + switch(wParam) + { + case MK_CONTROL: // Ctrl + Mouse movement + { + short iDist = HIWORD(wParam); + m_sfLapOpts.iZoomLevels += - moveY; + UpdateUI(UPDATE_MAP); + break; + } + case MK_LBUTTON: + { + // they're dragging! + m_sfLapOpts.flWindowShiftX += moveX; + m_sfLapOpts.flWindowShiftY -= moveY; + break; + } + case MK_MBUTTON: + { + // Dynamic update of All Data display + UpdateUI(UPDATE_ALLDATA); + break; + } + } + UpdateUI(UPDATE_MAP); + return 0; + } + case WM_LBUTTONDOWN: + { + const int x = LOWORD(lParam); + const int y = HIWORD(lParam); + // figure out if we should put focus on the main map + RECT rcMap; + HWND hWndMap = GetDlgItem(this->m_hWnd,IDC_DISPLAY); + GetClientRect(hWndMap,&rcMap); + if(x >= rcMap.left && x < rcMap.right && y >= rcMap.top && y < rcMap.bottom) + { + SetFocus(hWndMap); + return TRUE; + } + return FALSE; + } + // Left/Middle mouse button activates a modal window that dispalys all of the data for a given point in a table + case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: + case WM_LBUTTONDBLCLK: + { + if ( GetDlgItem(hWnd_AllData, IDC_ALLDATADISPLAY) && uMsg != WM_MBUTTONDOWN ) // If the window showing all of the lap data is present, let's kill it + { + if (GetWindowPlacement(hWnd_AllData, &w_AllDataWindow) ) + { + DestroyWindow(hWnd_AllData); + hWnd_AllData = NULL; + AD_hWnd = NULL; + } + return TRUE; + } + else // If the window showing all of the lap data isn't there, let's create it + { + DLGPROC ShowAllData = NULL; + if (!GetDlgItem(hWnd_AllData, IDC_ALLDATADISPLAY)) // Make sure that the display isn't already showing + { + // Create the window for displaying all of the data points for the selected laps + INITCOMMONCONTROLSEX InitCtrlEx; + InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitCtrlEx.dwICC = ICC_PROGRESS_CLASS; + InitCommonControlsEx(&InitCtrlEx); + hWnd_AllData = CreateDialog(NULL, MAKEINTRESOURCE (IDD_ALLDATADISPLAY), hWnd, (DLGPROC)ShowAllData); + AD_hWnd = GetDlgItem(hWnd_AllData,IDC_ALLDATADISPLAY); // All Data listview control + SetWindowPlacement(hWnd_AllData, &w_AllDataWindow); - // Let's get the output file name from the user. - TCHAR szTempPath[MAX_PATH]; - TCHAR szFileName[MAX_PATH], szTempName[MAX_PATH]; - if (PrintFlag) - { - GetTempPath(NUMCHARS(szTempPath),szTempPath); // Get the TEMP folder path - swprintf(szTempName,NUMCHARS(szTempName), L"%sTmpFile.bmp", szTempPath); - } - else - { - if(ArtGetSaveFileName(hWnd, L"Choose Filename to save as a JPEG File.", szFileName, NUMCHARS(szFileName),L"JPG Files (*.jpg)\0*.JPG\0\0")) - { - if(!str_ends_with(szFileName,L".jpg")) - { - wcsncat(szFileName,L".jpg", NUMCHARS(szFileName)); - } - } - else - { - break; - } - // Create a temporary BMP file, this is where we will save the screen capture. - swprintf(szTempName, NUMCHARS(szTempName), L"%s.bmp", szFileName); - } - - // Add the size of the headers to the size of the bitmap to get the total file size - DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); - - //Offset to where the actual bitmap bits start. - bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); - - //Size of the file - bmfHeader.bfSize = dwSizeofDIB; - - //bfType must always be BM for Bitmaps - bmfHeader.bfType = 0x4D42; //BM + // Set up the AllData list box columns + vector lstCols; + vector lstWidths; + lstCols.push_back(L"Data Channel"); + lstCols.push_back(L"Lap 1"); + lstCols.push_back(L"Lap 2"); + lstCols.push_back(L"Lap 3"); + lstCols.push_back(L"Lap 4"); + lstCols.push_back(L"Lap 5"); + lstCols.push_back(L"Lap 6"); + lstCols.push_back(L"Lap 7"); + lstCols.push_back(L"Lap 8"); + lstCols.push_back(L"Lap 9"); + lstCols.push_back(L"Lap 10"); + lstWidths.push_back(130); + lstWidths.push_back(60); + lstWidths.push_back(60); + lstWidths.push_back(60); + lstWidths.push_back(60); + lstWidths.push_back(60); + lstWidths.push_back(60); + lstWidths.push_back(60); + lstWidths.push_back(60); + lstWidths.push_back(60); + lstWidths.push_back(60); - // Open a handle to the TEMP BMP file and write the DIB to it - HANDLE hFile = CreateFile(szTempName, - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); + m_sfListBox.Init(AD_hWnd,lstCols,lstWidths); // Initialize the listview + ShowWindow(hWnd_AllData, SW_SHOW); // Show the listview + } - DWORD dwBytesWritten = 0; - WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); - WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); - WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL); - - //Close the handle for the file that was created - CloseHandle(hFile); + UpdateUI(UPDATE_MAP | UPDATE_ALLDATA); + return TRUE; + } + } + case WM_NOTIFY: + { + NMHDR* notifyHeader = (NMHDR*)lParam; + switch(wParam) + { + case IDC_LAPS: + switch(notifyHeader->code) + { + case LVN_ITEMCHANGED: + { + NMITEMACTIVATE* pDetails = (NMITEMACTIVATE*)notifyHeader; + if(pDetails->iItem >= 0) + { + UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); + } + return TRUE; + } + case LVN_COLUMNCLICK: + { + LPNMLISTVIEW pLVInfo = (LPNMLISTVIEW)lParam; + // User clicked the column header, let's re-sort the list + if (pLVInfo->iSubItem == SORTSTYLE_BYTIMEOFRACE && m_sfLapOpts.eSortPreference != SORTSTYLE_BYTIMEOFRACE) + { + m_sfLapOpts.eSortPreference = SORTSTYLE_BYTIMEOFRACE; + UpdateUI(UPDATE_DASHBOARD | UPDATE_LIST); + } + else if (pLVInfo->iSubItem == SORTSTYLE_BYLAPTIME && m_sfLapOpts.eSortPreference != SORTSTYLE_BYLAPTIME) + { + m_sfLapOpts.eSortPreference = SORTSTYLE_BYLAPTIME; + UpdateUI(UPDATE_DASHBOARD | UPDATE_LIST); + } + } + } + break; + case IDC_XAXIS: + switch(notifyHeader->code) + { + case LVN_ITEMCHANGED: + const set sel = m_sfXAxis.GetSelectedItemsData(); + if(sel.size() == 1) + { + m_eXChannel = (DATA_CHANNEL)*sel.begin(); // Just take the first selected item for our choice + NMITEMACTIVATE* pDetails = (NMITEMACTIVATE*)notifyHeader; + if(pDetails->iItem >= 0) // Single select Listview, requires special handling + { + UpdateUI(UPDATE_MAP| UPDATE_DASHBOARD | UPDATE_VALUES); + } + } + return TRUE; + } + break; + case IDC_YAXIS: + switch(notifyHeader->code) + { + case LVN_ITEMCHANGED: + const set sel = m_sfYAxis.GetSelectedItemsData2(); + if(sel.size() >= 1) + { + m_lstYChannels.clear(); + for(set::iterator i = sel.begin(); i != sel.end(); i++) + { + m_lstYChannels.push_back((DATA_CHANNEL)*i); + } + NMITEMACTIVATE* pDetails = (NMITEMACTIVATE*)notifyHeader; + if(pDetails->iItem >= 0) + { + UpdateUI(UPDATE_MAP| UPDATE_DASHBOARD | UPDATE_VALUES); + } + } + return TRUE; + } + break; + } // end switch on wParam - //Unlock and Free the DIB from the heap -// GlobalUnlock(hDIB); -// GlobalFree(hDIB); + LPNMLISTVIEW pnm = (LPNMLISTVIEW)lParam; + switch (pnm->hdr.code) // Switch for ListView coloring and painting routines + { + case NM_CUSTOMDRAW: + { + LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam; + enum i_Color + { + CLEAR, + RED, + GREEN, + BLUE, + LTGREY + }; - // Now let's convert this Bitmap into a JPEG file, if the user wants to save it. - if (SaveFlag) + if( pnm->hdr.hwndFrom == AD_hWnd) // First see if this is from the All Data Display LV control + { + SetWindowLong(hWnd_AllData, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam, wParam, GREEN)); + return TRUE; + } + else if( pnm->hdr.hwndFrom == HC_ShowSplits) // See if this is from the Sector Display LV control + { + SetWindowLong(hWndShowSplits, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam, wParam, GREEN)); + return TRUE; + } + switch (wParam) + { + case IDC_XAXIS: + case IDC_YAXIS: { - // Load the BMP from a temporary file on the disk, and convert it - jpge::params params; - params.m_no_chroma_discrim_flag = 0; - params.m_quality = 95; - params.m_subsampling = jpge::subsampling_t::H2V2; - params.m_two_pass_flag = 0; + SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam, wParam, LTGREY)); + return TRUE; + } + case IDC_LAPS: + { +// SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam, wParam, CLEAR)); // No LV coloring for Laps list + return TRUE; + } + case IDC_DATAVALUES: + { + SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam, wParam, CLEAR)); // No LV coloring for Values Display + return TRUE; + } + case IDC_ALLDATADISPLAY: // First see if this is from the All Data Display LV control + { + SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam, wParam, GREEN)); + return TRUE; + } + case IDC_SHOW_SECTORS: // See if this is from the Sector Display LV control + { + SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam, wParam, GREEN)); + return TRUE; + } + default: + { + SetWindowLong(hWnd, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam, wParam, BLUE)); // Color Blue if process gets here (unlikely) + return TRUE; + } + } - wstring strW(szFileName); // unicode -> const char* conversion - string strA(strW.begin(),strW.end()); // unicode -> const char* conversion + switch(lplvcd->nmcd.dwDrawStage) + { + case CDDS_PREPAINT : + return CDRF_NOTIFYITEMDRAW; - jpge::compress_image_to_jpeg_file(strA.c_str(),bi.biWidth,-bi.biHeight,4,(const jpge::uint8*)lpbitmap,params); + case CDDS_ITEMPREPAINT: + if ( b_GreyColor) // Let's paint it with grey background + { + lplvcd->clrText = RGB(0,0,0); // Black text + lplvcd->clrTextBk = RGB(200,200,200); // Grey background + b_GreyColor = !b_GreyColor; + } + else + { + lplvcd->clrText = RGB(0,0,0); // Black text + lplvcd->clrTextBk = RGB(255,255,255); // White background + } - DeleteFile(szTempName); // Remove the TEMP file - //Unlock and Free the DIB from the heap - GlobalUnlock(hDIB); - GlobalFree(hDIB); - } - else if (PrintFlag) - { - //Unlock and Free the DIB from the heap - GlobalUnlock(hDIB); - GlobalFree(hDIB); + // At this point, you can change the background colors for the item + // and any subitems and return CDRF_NEWFONT. If the list-view control + // is in report mode, you can simply return CDRF_NOTIFYSUBITEMDRAW + // to customize the item's subitems individually - //////////////////////////////////////////////////////////////////////////////// - cxsize=0, cxpage=0; - cysize=0, cypage=0; - PAINTSTRUCT ps; + if (pnm->hdr.hwndFrom == HC_ShowSplits || pnm->hdr.hwndFrom == AD_hWnd) + { + return CDRF_NOTIFYSUBITEMDRAW; // Returns this to start the SubItem painting + } + else + { + return CDRF_NEWFONT; // No subitem painting, reduce overhead + } - // Let's get the Bitmap image for printing - { - ZeroMemory(&hBitmap, sizeof(HBITMAP)); + case CDDS_SUBITEM | CDDS_ITEMPREPAINT: // SubItem painting routines + if ( lplvcd->iSubItem == i_SubItemBest) // Best time/value, let's paint it with green background + { + lplvcd->clrText = RGB(0,0,0); // Black text + lplvcd->clrTextBk = RGB(20,230,20); // Green background + } + if ( lplvcd->iSubItem == i_SubItemWorst) // Worst time/value, let's paint it with green background + { + lplvcd->clrText = RGB(0,0,0); // Black text + lplvcd->clrTextBk = RGB(230,20,20); // Red background + } - hBitmap = (HBITMAP)LoadImage(NULL,szTempName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE|LR_VGACOLOR); - if(hBitmap) - { - cxpage = GetDeviceCaps (hdc, HORZRES); - cypage = GetDeviceCaps (hdc, VERTRES); - GetObject(hBitmap,sizeof(BITMAP),&bitmap); - bxWidth = bitmap.bmWidth; - bxHeight = bitmap.bmHeight; - } - - // Let's paint the image into a Device Context - hdc = BeginPaint(hWnd, &ps); - hdcMem = CreateCompatibleDC(hdc); - SelectObject(hdcMem, hBitmap); - SetMapMode (hdc, MM_ISOTROPIC); - SetWindowExtEx(hdc, cxpage,cypage, NULL); - SetViewportExtEx(hdc, cxsize, cysize,NULL); - SetViewportOrgEx(hdc, 0, 0, NULL); - SetStretchBltMode(hdc,COLORONCOLOR); - StretchBlt(hdc, 0, 0, bxWidth, bxHeight, hdcMem, 0, 0,bxWidth,bxHeight, SRCCOPY); + // This notification is received only if you are in report mode and + // returned CDRF_NOTIFYSUBITEMDRAW in the previous step. At + // this point, you can change the background colors for the + // subitem and return CDRF_NEWFONT. - EndPaint(hWnd, &ps); - DeleteDC(hdcMem); + return CDRF_NEWFONT; + default: + return CDRF_DODEFAULT; + } + } + default: + return CDRF_DODEFAULT; + } + } // end body of case WM_NOTIFY + case WM_COMMAND: + { + switch(LOWORD(wParam)) // find out the control ID + { + case IDC_SENDMESSAGE: + { + static MESSAGEDLG_RESULT sfResult; + if(wcslen(sfResult.szMessage) <= 0) + { + wcscpy_s( sfResult.szMessage, L"Pit Now"); // Add default string if nothing is there + } + CMessageDlg dlgMessage(&sfResult); + + HWND hWndButton = GetDlgItem(this->m_hWnd,IDC_SENDMESSAGE); + EnableWindow(hWndButton,FALSE); + ArtShowDialog(&dlgMessage); + EnableWindow(hWndButton,TRUE); + LPCTSTR lpsz = g_pLapDB->GetNetStatus(NETSTATUS_REMOTEIP); + sprintf(sfResult.szIP, "%S", lpsz); - // Now let's print the loaded image - DOCINFO di= { sizeof (DOCINFO), TEXT ("Printing Picture...")}; - HDC prn = NULL; - // Open up the standard printer dialog and get our printer DC - prn = GetPrinterDC(hWnd); + if(!sfResult.fCancelled) + { + // now that we're done, we should have a result! + SendMsg(sfResult, this); + } + return TRUE; + } + case IDOK: + { + return TRUE; + } + case ID_OPTIONS_KMH: + { + m_sfLapOpts.eUnitPreference = UNIT_PREFERENCE_KMH; + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_MPH: + { + m_sfLapOpts.eUnitPreference = UNIT_PREFERENCE_MPH; + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_MS: + { + m_sfLapOpts.eUnitPreference = UNIT_PREFERENCE_MS; + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_VERTICAL_LANDSCAPE: + { + m_sfLapOpts.e_Orientation = VERTICAL_LANDSCAPE; + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_VERTICAL_PORTRAIT: + { + m_sfLapOpts.e_Orientation = VERTICAL_PORTRAIT; + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_FLAT_LANDSCAPE: + { + m_sfLapOpts.e_Orientation = FLAT_LANDSCAPE; + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_FLAT_PORTRAIT: + { + m_sfLapOpts.e_Orientation = FLAT_PORTRAIT; + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_XAXIS_KM: + { + m_sfLapOpts.bXAxis_KM = XAXIS_PREFERENCE_KM; + CExtendedLap::SetDistance(m_sfLapOpts.bXAxis_KM); // Set the X Axis as read from SETTINGS.TXT file + MessageBox(hWnd, L"X-Axis will be displayed in KM's\n\nYou need to re-load the Race Session for this change to take effect!",L"NOTICE", MB_OK); + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_XAXIS_LAT: + { + m_sfLapOpts.bXAxis_KM = XAXIS_PREFERENCE_LAT; + CExtendedLap::SetDistance(m_sfLapOpts.bXAxis_KM); // Set the X Axis as read from SETTINGS.TXT file + MessageBox(hWnd, L"X-Axis will be displayed in Latitude/Longitudinal degrees\n\nYou need to re-load the Race Session for this change to take effect!",L"NOTICE", MB_OK); + UpdateUI(UPDATE_MAP | UPDATE_MENU); + return TRUE; + } + case ID_OPTIONS_SHOWBESTS: + { + m_fShowBests = !m_fShowBests; + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); + return TRUE; + } + case ID_OPTIONS_SHOWREFERENCELAP: + { + m_fShowReferenceLap = !m_fShowReferenceLap; + m_sfLapOpts.bShowReferenceLap = m_fShowReferenceLap; + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); + return TRUE; + } + case ID_OPTIONS_DRAWLINES: + { + m_sfLapOpts.fDrawLines = !m_sfLapOpts.fDrawLines; + UpdateUI(UPDATE_MENU | UPDATE_MAP); + return TRUE; + } + case ID_OPTIONS_BACKGROUND: + { + m_sfLapOpts.fColorScheme = !m_sfLapOpts.fColorScheme; + UpdateUI(UPDATE_MENU | UPDATE_MAP); + return TRUE; + } + case ID_OPTIONS_IOIO5VSCALE: + { + m_sfLapOpts.fIOIOHardcoded = !m_sfLapOpts.fIOIOHardcoded; + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD); + return TRUE; + } + case ID_OPTIONS_SHOWDRIVERBESTS: + { + m_fShowDriverBests = !m_fShowDriverBests; + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); + return TRUE; + } + case ID_DATA_SWITCHSESSION: + { + static bool bSwitchSession; // Flag to prevent multiple windows from being opened + if (!bSwitchSession) + { + RACESELECT_RESULT sfResult; + bSwitchSession = true; + // Zero out the Race ID's before selecting them + for (int z = 0; z < 50; z++) + { + m_iRaceId[z] = -1; + sfResult.iRaceId[z] = -1; + } + + CRaceSelectDlg dlgRace(g_pLapDB, &sfResult); + ArtShowDialog(&dlgRace); - // Let's set up the printer for Landscape Mode printing -// TCHAR pDevice[MAX_PATH]; -// swprintf(pDevice, NUMCHARS(pDevice), L"PrinterName, Job 0001"); -// GetLandscapeDevMode(hWnd, pDevice, (HANDLE)prn); + if(!sfResult.fCancelled) + { + for (int z = 0; z < 50; z++) + { + m_iRaceId[z] = sfResult.iRaceId[z]; // Load all of the race sessions chosen + } + ClearUILaps(); + LoadLaps(g_pLapDB); + UpdateUI(UPDATE_ALL); - if (prn) + // Find all of the Names of the selected Race Sessions for addition to title bar + vector lstRaces = g_pLapDB->GetRaces(); + TCHAR lstSessions[MAX_PATH] = {NULL}; + for(int x = 0;x < lstRaces.size(); x++) + { + for (int z = 0; z < 50; z++) + { + if ( m_iRaceId[z] == lstRaces[x].raceId ) { - cxpage = GetDeviceCaps (prn, HORZRES); - cypage = GetDeviceCaps (prn, VERTRES); - hdcMem = CreateCompatibleDC(prn); - HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hBitmap); + _snwprintf(lstSessions, NUMCHARS(lstSessions), L"%s | %s", lstSessions, lstRaces[x].strName.c_str()); + break; + } + } + } + + TCHAR szTemp[MAX_PATH] = {NULL}; + _snwprintf(szTemp, NUMCHARS(szTemp), L"Pitside - %s%s", m_szPath, lstSessions); + SetWindowText(m_hWnd, szTemp ); // Change the title bar to show the file name and Session(s) opened - StartDoc (prn, &di); - StartPage (prn) ; - SetMapMode (prn, MM_ISOTROPIC); - SetWindowExtEx(prn, cxpage,cypage, NULL); - SetViewportExtEx(prn, cxpage, cypage,NULL); + // Just loaded a new session. Let's reset the timer + tmLast = timeGetTime(); // Save last time lap was received + } + bSwitchSession = false; + } + return TRUE; + } + case ID_DATA_EDITSESSION: + { + RACESELECTEDIT_RESULT sfResult; + static bool bEditSessions; // Flag to prevent multiple windows from being opened + if (!bEditSessions) + { + bEditSessions = true; + CRaceSelectEditDlg dlgRace(g_pLapDB, &sfResult); + ArtShowDialog(&dlgRace); - SetViewportOrgEx(prn, 0, 0, NULL); - StretchBlt(prn, 0, 0, cxpage, cypage, hdcMem, 0, 0,bxWidth,bxHeight, SRCCOPY); - EndPage (prn); - EndDoc(prn); - DeleteDC(prn); - SelectObject(hdcMem, hbmOld); - DeleteDC(hdcMem); - } - DeleteFile(szTempName); - //////////////////////////////////////////////////////////////////////////////// - } - } - } - else - { - // User wants to copy image to Clipboard. + if(!sfResult.fCancelled) + { + m_iRaceId[0] = sfResult.iRaceId; + ClearUILaps(); + LoadLaps(g_pLapDB); + UpdateUI(UPDATE_MAP | UPDATE_MENU | UPDATE_DASHBOARD ); + } + bEditSessions = false; + } + return TRUE; + } + case ID_OPTIONS_PLOTPREFS: + { + bool static bSetPlot; + PLOTSELECT_RESULT sfResult; + if (!bSetPlot) // Prevent duplicate windows from appearing + { + bSetPlot = true; + CPlotSelectDlg dlgPlot(g_pLapDB, &sfResult, m_iRaceId[0], &m_sfLapOpts); + ArtShowDialog(&dlgPlot); + bSetPlot = false; + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); + } + return TRUE; + } + case ID_OPTIONS_SETSPLITS: + { + bool static bSetSplits; + SETSPLITSDLG_RESULT sfResult; + if (!bSetSplits) // Prevent duplicate windows from appearing + { + bSetSplits = true; + CSetSplitsDlg dlgSetSplits(g_pLapDB, m_pReferenceLap, &sfResult, m_iRaceId[0], &m_sfLapOpts); + ArtShowDialog(&dlgSetSplits); + bSetSplits = false; + } + else + { + return TRUE; + } - //Unlock and Free the DIB from the heap - GlobalUnlock(hDIB); - GlobalFree(hDIB); + const int cSectors = 9; // Maximum numbers of Split Times + const int MaxLaps = 8; // Maximum number of laps to display + if (!IsWindow(hWndShowSplits) && m_sfLapOpts.fDrawSplitPoints) + { + // Create non-modal dialog to display the sector times window if DrawSplitPoints is TRUE + DLGPROC ShowSplits = NULL; + // Create the window for displaying sector times for the selected laps + INITCOMMONCONTROLSEX InitCtrlEx; + InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitCtrlEx.dwICC = ICC_PROGRESS_CLASS; + InitCommonControlsEx(&InitCtrlEx); + hWndShowSplits = CreateDialog(NULL, MAKEINTRESOURCE (IDD_SHOWSECTORS), hWnd, (DLGPROC)ShowSplits); // Create resource + HC_ShowSplits = GetDlgItem(hWndShowSplits, IDC_SHOW_SECTORS); // Let's get the handle for the display control in this window + SetWindowPlacement(hWndShowSplits, &w_SectorTimesWindow); // Maintains the location of the Sector Times window - // Add the size of the headers to the size of the bitmap to get the total DIB size - DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); - - //Offset to where the actual bitmap bits start. - bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); - - //Size of the file - bmfHeader.bfSize = dwSizeofDIB; - - //bfType must always be BM for Bitmaps - bmfHeader.bfType = 0x4D42; //BM + // Set up the Sector Times list box columns + vector lstCols; + vector lstWidths; + lstCols.push_back(L"Lap ID"); + lstCols.push_back(L"1"); + lstCols.push_back(L"2"); + lstCols.push_back(L"3"); + lstCols.push_back(L"4"); + lstCols.push_back(L"5"); + lstCols.push_back(L"6"); + lstCols.push_back(L"7"); + lstCols.push_back(L"8"); + lstCols.push_back(L"9"); + lstWidths.push_back(195); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); + lstWidths.push_back(40); - // lpbitmap is the pointer to the BMP byte array - { - char* bitmapBuffer = lpbitmap; - size_t buflen = dwSizeofDIB; -// size_t buflen = dwBmpSize; - - copyBitmapToClipboard(bitmapBuffer, buflen); + m_sfListBox.Init(HC_ShowSplits,lstCols,lstWidths); // Initialize and show the Sector Splits window + ShowWindow(hWndShowSplits, SW_SHOW); + } + else if (!m_sfLapOpts.fDrawSplitPoints) + { + if (HC_ShowSplits) // If the window showing all of the lap data is present, let's kill it + { + if (GetWindowPlacement(hWndShowSplits, &w_SectorTimesWindow) ) + { + DestroyWindow(hWndShowSplits); + hWndShowSplits = NULL; + } + } + } + if(!sfResult.fCancelled) + { + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_TRACTIONCIRCLE | UPDATE_DASHBOARD); + } + return TRUE; + } + case ID_OPTIONS_CANCELSPLITS: + { + if (HC_ShowSplits) // If the window showing all of the lap data is present, let's kill it + { + if (GetWindowPlacement(hWndShowSplits, &w_SectorTimesWindow) ) + { + DestroyWindow(hWndShowSplits); + hWndShowSplits = NULL; + } + } + m_sfLapOpts.fDrawSplitPoints = false; + return TRUE; + } + case ID_HELP_SHOWHELP: + { + ShowHelp(hWnd); + return TRUE; + } + case ID_HELP_SHOWWFLHELP: + { + ShowWFLHelp(hWnd); + return TRUE; + } + case ID_HELP_IPS: + { + ShowNetInfo(); + return TRUE; + } + case ID_HELP_ABOUT: + { + ABOUT_RESULT sfResult; + CAboutDlg dlgAbout(&sfResult); + ArtShowDialog(&dlgAbout); + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_TRACTIONCIRCLE | UPDATE_DASHBOARD); + return TRUE; + } + case ID_OPTIONS_TRACTIONCIRCLE: + { + m_fShowTractionCircle = !m_fShowTractionCircle; + m_sfLapOpts.bTractionCircle = m_fShowTractionCircle; + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_TRACTIONCIRCLE); + return TRUE; + } + case ID_OPTIONS_SMOOTH: + { + m_sfLapOpts.bSmoothYesNo = !m_sfLapOpts.bSmoothYesNo; + UpdateUI(UPDATE_MENU | UPDATE_MAP | UPDATE_TRACTIONCIRCLE); + return TRUE; + } + // Nested loop for the following functions + case ID_EDIT_COPY: + { + // Option is not working and causes crashes right now, so disable it + return TRUE; + } + case IDM_PRINT_BM: + case IDM_SAVE_BM: + { + int SaveFlag = false, PrintFlag = false; + // Set flag to sending image to Clipboard, if requested by user + if (LOWORD(wParam) == IDM_SAVE_BM) + SaveFlag = true; + if (LOWORD(wParam) == IDM_PRINT_BM) + PrintFlag = true; + + // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF + // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO + // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + // PARTICULAR PURPOSE. + // + // Copyright (c) Microsoft Corporation. All rights reserved -// DWORD dwBytesWritten = 0; -// WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); -// WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); -// WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL); + // + // FUNCTION: CaptureAnImage(HWND hWnd) + // + // PURPOSE: Captures a screenshot into a window and then saves it in a .bmp file. + // + // COMMENTS: + // + // Note: This sample will attempt to create a file called captureqwsx.bmp + // - } - } - //Unlock and Free the DIB from the heap - GlobalUnlock(hDIB); - GlobalFree(hDIB); - DeleteObject(hbmSource); - DeleteObject(hdcMemDC); - ReleaseDC(NULL,hdcSource); - ReleaseDC(hWnd,hdcWindow); - UpdateUI(UPDATE_DASHBOARD | UPDATE_LIST | UPDATE_MENU | UPDATE_ALL); -// InitAxes(setSelectedChannels); - return TRUE; - } - case ID_FILE_EXIT: - { - DestroyWindow(hWnd); - break; - } - case ID_TIMINGSCORING: - { - // Let's set up for displaying the T&S page - int m_RaceId[50] = {NULL}; - // Show the race-selection dialog and let the User pick which ones to use on T&S page - SELECTSESSIONS_RESULT sfResult; - CDlgSelectSessions dlgRace(g_pLapDB, &sfResult); - ArtShowDialog(&dlgRace); - - if(!sfResult.fCancelled && sfResult.m_RaceId[0] != -1) - { - // Now display the T&S page and pass these RaceID's to this class - TS_RESULT ts_sfResult; - CDlgTimingScoring dlgTS(g_pLapDB, &ts_sfResult, m_szPath, &sfResult); - ArtShowDialog(&dlgTS); - } - return TRUE; - } - case ID_DATA_OPENDB: - { - TCHAR szFilename[MAX_PATH]; - if(ArtGetOpenFileName(hWnd, L"Choose WFLP file", szFilename, NUMCHARS(szFilename),L"WifiLapper Files (*.wflp)\0*.WFLP\0\0")) - { - if(g_pLapDB->Init(szFilename)) - { - _snwprintf(m_szPath, NUMCHARS(m_szPath), szFilename); - RACESELECT_RESULT sfResult; - - // Zero out the Race ID's before selecting them - for (int z = 0; z < 50; z++) - { - m_iRaceId[z] = -1; - sfResult.iRaceId[z] = -1; - } - - CRaceSelectDlg dlgRace(g_pLapDB, &sfResult); - ArtShowDialog(&dlgRace); - - if(!sfResult.fCancelled) - { - for (int z = 0; z < 50; z++) - { - m_iRaceId[z] = sfResult.iRaceId[z]; // Load all of the race sessions chosen - } - ClearUILaps(); - LoadLaps(g_pLapDB); - UpdateUI(UPDATE_ALL); - // Let's reset the timer - tmLast = timeGetTime(); // Save last time lap was received - } - } - } - return TRUE; - } - case ID_DATA_DASHWARE: - { - set setSelectedData = m_sfLapList.GetSelectedItemsData(); - if(setSelectedData.size() > 0) - { - TCHAR szFilename[MAX_PATH]; - if(ArtGetSaveFileName(hWnd, L"Choose Output file", szFilename, NUMCHARS(szFilename),L"CSV Files (*.csv)\0*.CSV\0\0")) - { - // let's make sure there's a .csv suffix on that bugger. - if(!str_ends_with(szFilename,L".csv")) - { - wcsncat(szFilename,L".csv", NUMCHARS(szFilename)); - } - - // Display the "Working...." dialog, as this is going to take some time. - DLGPROC working = NULL; - HWND hwndGoto = NULL; // Window handle of dialog box - if (!IsWindow(hwndGoto)) - { - hwndGoto = CreateDialog(NULL, MAKEINTRESOURCE (IDD_PROGRESS), hWnd, working); - ShowWindow(hwndGoto, SW_SHOW); - } - - vector lstLaps; - map mapData; - for(set::iterator i = setSelectedData.begin(); i != setSelectedData.end(); i++) - { - CExtendedLap* pLap = (CExtendedLap*)*i; - - for(int x = 0;x < DATA_CHANNEL_COUNT; x++) - { - const IDataChannel* pChannel = g_pLapDB->GetDataChannel(pLap->GetLap()->GetLapId(),(DATA_CHANNEL)x); - mapData[pLap->GetLap()] = pChannel; - } - lstLaps.push_back(pLap->GetLap()); - } - DashWare::SaveToDashware(szFilename, lstLaps); - DestroyWindow(hwndGoto); // Close the "Working..." dialog - hwndGoto = NULL; - } - } - else - { - MessageBox(NULL,L"Please Select Laps",L"You must select some laps first!",MB_OK | MB_ICONWARNING); - } - return TRUE; - } - case IDC_DISPLAYTYPE_LINE: - { - switch(HIWORD(wParam)) - { - case BN_CLICKED: - m_eLapDisplayStyle = LAPDISPLAYSTYLE_MAP; - UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - break; - } - return TRUE; - } - case IDC_DISPLAYTYPE_RECEPTION: - { - switch(HIWORD(wParam)) - { - case BN_CLICKED: - m_eLapDisplayStyle = LAPDISPLAYSTYLE_RECEPTION; - UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - break; - } - return TRUE; - } - case IDC_DISPLAYTYPE_PLOT: - { - switch(HIWORD(wParam)) - { - case BN_CLICKED: - m_eLapDisplayStyle = LAPDISPLAYSTYLE_PLOT; - UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - break; - } - return TRUE; - } - case IDC_SETREFERENCE: - { - // they want to set a given lap as a reference lap - set setSelected = m_sfLapList.GetSelectedItemsData(); - if(setSelected.size() == 1) - { - CExtendedLap* pNewRefLap = (CExtendedLap*)*(setSelected.begin()); - pNewRefLap->ComputeDistances(NULL, g_pLapDB); - for(map::iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) - { - if(i->second != pNewRefLap) - { - i->second->ComputeDistances(pNewRefLap, g_pLapDB); // tell this lap to recompute using pLap as the reference lap - } - } - m_pReferenceLap = pNewRefLap; - // Tell it to close Sector Display and release all Split Points - // Blah blah blah - } - else - { - // what's going on? This should've been disabled - } - UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - return TRUE; - } - case IDC_SETDRIVER: // they want to set the driver of the selected laps - { - switch(HIWORD(wParam)) - { - case BN_CLICKED: - ApplyDriverNameToSelectedLaps(::g_pLapDB); - UpdateUI(UPDATE_ALL); //the list causes everything to redraw - break; - } - return TRUE; - } - case IDC_CLEARSELECTION: - { - switch(HIWORD(wParam)) - { - case BN_CLICKED: - m_sfLapList.Clear(); - UpdateUI(UPDATE_ALL); - break; - } - return TRUE; - } - case IDC_COMMENTTEXT: - { - switch(HIWORD(wParam)) - { - case EN_CHANGE: - { - SendMessage(GetDlgItem(m_hWnd, IDC_COMMENTTEXT), WM_GETTEXT, NUMCHARS(m_szCommentText), (LPARAM)m_szCommentText); -// UpdateUI(UPDATE_LIST | UPDATE_DASHBOARD); - break; - } - } - return TRUE; - } - } // end switch for finding out what control WM_COMMAND hit - break; // break out of WM_COMMAND handling - } - case WM_UPDATEUI: - { - DWORD dwCurrentUpdate = m_fdwUpdateNeeded; - UpdateUI_Internal(dwCurrentUpdate); - m_fdwUpdateNeeded &= ~dwCurrentUpdate; - return TRUE; - } - case WM_NOTIFYUPDATE: - { - switch(wParam) - { - case NOTIFY_NEEDRECVCONFIG: - { - // a lap has been received, but the database isn't set up to receive (aka it's pointing at a high-quality race). - // let's tell the user about it and ask them for input. - static bool fWarnedOnce = false; - if(!fWarnedOnce) - { - fWarnedOnce = true; - MessageBox(NULL,L"You just received a lap from a car, but you're looking at old data. Hit data->'new race session' or else Pitside will keep ignoring it",L"Not ready to receive",0); - } - return TRUE; - } - case NOTIFY_NEWLAP: - { - ILapReceiver* pLapDB = (ILapReceiver*)lParam; - int iLastRaceId = pLapDB->GetLastReceivedRaceId(); - if(m_iRaceId[0] < 0 || pLapDB->GetLapCount(m_iRaceId[0]) <= 0 || // if we don't have a race or our current race has no laps (aka sucks) - (pLapDB->IsActivelyReceiving(iLastRaceId) && !pLapDB->IsActivelyReceiving(m_iRaceId[0]))) // or if the new race ID is receiving and the current race ID isn't... - { - m_iRaceId[0] = pLapDB->GetLastReceivedRaceId(); // since we just got told there's a new lap, there must be a last-received-race - ClearUILaps(); - LoadLaps(g_pLapDB); - UpdateUI(UPDATE_ALL); - } - else - { - LoadLaps((ILapReceiver*)lParam); - UpdateUI(UPDATE_LIST | UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); - } - // Just loaded a new lap. Let's reset the timer - tmLast = timeGetTime(); // Save last time lap was received - return TRUE; - } - case NOTIFY_NEWDATABASE: - { - // a new database has shown up! - - // first, check if the user cares... - DWORD dwRet = MessageBox(NULL,L"A new database has been sent from a phone. Do you want to load it?",L"New database",MB_YESNO); - if(dwRet == IDYES) - { - LPCTSTR lpszFilename = (LPCTSTR)lParam; - if(g_pLapDB->Init(lpszFilename)) - { - RACESELECT_RESULT sfResult; - - // Zero out the Race ID's before selecting them - for (int z = 0; z < 50; z++) - { - m_iRaceId[z] = -1; - sfResult.iRaceId[z] = -1; - } - - CRaceSelectDlg dlgRace(g_pLapDB, &sfResult); - ArtShowDialog(&dlgRace); - if(!sfResult.fCancelled) - { - for (int z = 0; z < 50; z++) - { - m_iRaceId[z] = sfResult.iRaceId[z]; // Load all of the race sessions chosen - } - - ClearUILaps(); - LoadLaps(g_pLapDB); - UpdateUI(UPDATE_ALL); - } - } - // Let's reset the timer - tmLast = timeGetTime(); // Save last time lap was received - } - return TRUE; - - } - case NOTIFY_NEWNETSTATUS: - { - ILapReceiver* pLaps = (ILapReceiver*)lParam; - SendMessage(m_hWnd, WM_SETTEXT, 0, (LPARAM)pLaps->GetNetStatus(NETSTATUS_STATUS)); - - TCHAR szTemp[512]; -// HWND hWndIp = GetDlgItem(m_hWnd, IDC_CURRENTIP); -// swprintf(szTemp, NUMCHARS(szTemp), L"PC: %s", pLaps->GetNetStatus(NETSTATUS_THISIP)); -// SendMessage(hWndIp, WM_SETTEXT, 0, (LPARAM)szTemp); - - HWND hWndRemoteIp = GetDlgItem(m_hWnd, IDC_CURRENTREMOTEIP); - swprintf(szTemp, NUMCHARS(szTemp), L"Phone: %s", pLaps->GetNetStatus(NETSTATUS_REMOTEIP)); - SendMessage(hWndRemoteIp, WM_SETTEXT, 0, (LPARAM)szTemp); - return TRUE; - } - case NOTIFY_NEWMSGDATA: - { - CMsgThread* pThd = (CMsgThread*)lParam; - pThd->GetStatusMessage(m_szMessageStatus, NUMCHARS(m_szMessageStatus)); - UpdateUI(UPDATE_DASHBOARD); - return TRUE; - } - } - - return 0; - } - case WM_RBUTTONUP: - { - m_sfLapOpts.flWindowShiftX = 0; - m_sfLapOpts.flWindowShiftY = 0; - m_sfLapOpts.iZoomLevels = 0; - UpdateUI(UPDATE_MAP); - return TRUE; - } - case WM_PAINT: - { - UpdateDisplays(); - return FALSE; - } - case WM_SIZE: - { - SIZE sNewSize; - sNewSize.cx = LOWORD(lParam); - sNewSize.cy = HIWORD(lParam); - HandleResize(sNewSize); - return TRUE; - } - } - - return FALSE; - } - DWORD GetDlgId() const {return IDD_DLGFIRST;} - - const static DWORD UPDATE_MAP = 0x1; - const static DWORD UPDATE_LIST = 0x2; - const static DWORD UPDATE_DASHBOARD = 0x4; - const static DWORD UPDATE_MENU = 0x8; - const static DWORD UPDATE_VALUES = 0x10; - const static DWORD UPDATE_TRACTIONCIRCLE = 0x20; - - const static DWORD UPDATE_ALL = 0xffffffff; - // Pull in PlotPrefs array as well as lines vs. dots and Painting color scheme settings from Settings.txt file - void SetDisplayOptions(const LAPSUPPLIEROPTIONS& lapOpts) - { - m_sfLapOpts = lapOpts; - } - void SetDBPath(const TCHAR szPath[MAX_PATH]) - { - _snwprintf(m_szPath, NUMCHARS(m_szPath), szPath); - } - - void UpdateUI(DWORD fdwUpdateFlags) - { - m_fdwUpdateNeeded|= fdwUpdateFlags; - PostMessage(m_hWnd,WM_UPDATEUI,0,0); - } - void UpdateUI_Internal(DWORD fdwUpdateFlags) - { - set setSelectedData = m_sfLapList.GetSelectedItemsData(); - vector laps = GetSortedLaps(m_sfLapOpts.eSortPreference); // translates our m_mapLaps into a vector sorted by time - // do some memory cleanup - for(int x = 0;x < laps.size(); x++) - { - if(setSelectedData.find((LPARAM)laps[x]) != setSelectedData.end() || laps[x] == m_pReferenceLap) - { - // this lap is still selected, as it is in the set of selected items - } - else - { - // this lap is not selected. we should compact it so that it doesn't gobble memory. - laps[x]->Compact(); - } - } - - - if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_LIST)) - { - int iPosition = m_sfLapList.GetPosition(); - m_sfLapList.Clear(); - vector laps = GetSortedLaps(m_sfLapOpts.eSortPreference); // translates our m_mapLaps into a vector sorted by time - for(int x = 0;x < laps.size(); x++) - { - vector lstStrings; - laps[x]->GetStrings(lstStrings); - m_sfLapList.AddStrings(lstStrings, (LPARAM)laps[x]); - } - m_sfLapList.SetSelectedData(setSelectedData); - if(laps.size() > 0) - { - m_sfLapList.MakeVisible((LPARAM)laps[laps.size()-1]); - } - } - if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_VALUES)) - { - UpdateValues(); - UpdateSectors(); - } - if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_MAP)) - { - UpdateDisplays(); - } - if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_MENU)) - { - UpdateMenus(); - } - - if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_DASHBOARD)) - { - set setSelectedChannels; - - for(set::const_iterator i = setSelectedData.begin(); i != setSelectedData.end(); i++) - { - CExtendedLap* pLap = (CExtendedLap*)(*i); - set setLapData = pLap->GetAvailableChannels(); - for(set::iterator i = setLapData.begin(); i != setLapData.end(); i++) - { - setSelectedChannels.insert(*i); - } - } - - CASSERT(LAPDISPLAYSTYLE_COUNT == 4); - switch(m_eLapDisplayStyle) - { - case LAPDISPLAYSTYLE_MAP: CheckRadioButton(m_hWnd, IDC_DISPLAYTYPE_LINE, IDC_DISPLAYTYPE_LAST, IDC_DISPLAYTYPE_LINE); break; - case LAPDISPLAYSTYLE_PLOT: CheckRadioButton(m_hWnd, IDC_DISPLAYTYPE_LINE, IDC_DISPLAYTYPE_LAST, IDC_DISPLAYTYPE_PLOT); break; - case LAPDISPLAYSTYLE_RECEPTION: CheckRadioButton(m_hWnd, IDC_DISPLAYTYPE_LINE, IDC_DISPLAYTYPE_LAST, IDC_DISPLAYTYPE_RECEPTION); break; - default: DASSERT(FALSE); break; - } - - set setXSelected,setYSelected; - setXSelected.insert(m_eXChannel); - m_sfXAxis.SetSelectedData(setXSelected); - - for(int x = 0; x < m_lstYChannels.size(); x++) - { - setYSelected.insert(m_lstYChannels[x]); - } - m_sfYAxis.SetSelectedData(setYSelected); - - HWND hDriverButton = GetDlgItem(m_hWnd, IDC_SETDRIVER); - Button_Enable(hDriverButton, setSelectedData.size() > 0); - HWND hReferenceButton = GetDlgItem(m_hWnd, IDC_SETREFERENCE); - Button_Enable(hReferenceButton, setSelectedData.size() == 1); - - HWND hWndReference = GetDlgItem(m_hWnd, IDC_CURRENTREFERENCE); - if(m_pReferenceLap) - { - TCHAR szRefString[512] = L""; - TCHAR szLapString[512] = L""; - m_pReferenceLap->GetString(szLapString, NUMCHARS(szLapString)); - swprintf(szRefString, NUMCHARS(szRefString), L"Reference Lap: %s", szLapString); - SendMessage(hWndReference, WM_SETTEXT, 0, (LPARAM)szRefString); - } - else - { - SendMessage(hWndReference, WM_SETTEXT, 0, (LPARAM)L"No Reference Lap"); - } - - HWND hWndMessageStatus = GetDlgItem(m_hWnd, IDC_MESSAGESTATUS); - SendMessage(hWndMessageStatus, WM_SETTEXT, 0, (LPARAM)m_szMessageStatus); - - InitAxes(setSelectedChannels); - } - } -private: - void ClearUILaps() - { - m_mapLapHighlightTimes.clear(); - m_pReferenceLap = NULL; - m_mapLaps.clear(); - m_sfLapList.Clear(); - } - bool ShowHelp(HWND hWnd) - { - TCHAR lpOpen[MAX_PATH] = L"open"; - - TCHAR lpFile[MAX_PATH] = L"PitsideHelp.pdf"; - TCHAR lpDir[MAX_PATH]; - if(GetAppFolder(lpDir,NUMCHARS(lpDir))) - { - // Set up the Filename string for the Help PDF file. - wcsncat(lpDir,L"", NUMCHARS(lpDir)-1); - } - else - { - // trouble. just bail. - return false; - } - int nShowCmd = SW_RESTORE; // Restore the Help document, if it is minimized or whatever. - - // Shell to the Help PDF file - HINSTANCE Check = ShellExecuteW(hWnd, lpOpen, lpFile, NULL, lpDir, nShowCmd); - if ((int)Check <= 32) - MessageBox(NULL, L"The Help file requires Acrobat Reader\n\nPlease install Reader and try again", L"Acrobat Reader Not Found", MB_OK); - return true; - } - bool ShowWFLHelp(HWND hWnd) - { - TCHAR lpOpen[MAX_PATH] = L"open"; - - TCHAR lpFile[MAX_PATH] = L"WifilapperHelp.pdf"; - TCHAR lpDir[MAX_PATH]; - if(GetAppFolder(lpDir,NUMCHARS(lpDir))) - { - // Set up the Filename string for the Help PDF file. - wcsncat(lpDir,L"", NUMCHARS(lpDir)-1); - } - else - { - // trouble. just bail. - return false; - } - int nShowCmd = SW_RESTORE; // Restore the Help document, if it is minimized or whatever. - - // Shell to the Help PDF file - HINSTANCE Check = ShellExecuteW(hWnd, lpOpen, lpFile, NULL, lpDir, nShowCmd); - if ((int)Check <= 32) - MessageBox(NULL, L"The Help file requires Acrobat Reader\n\nPlease install Reader and try again", L"Acrobat Reader Not Found", MB_OK); - return true; - } - void ShowNetInfo() - { - while(true) - { - TCHAR szBuf[1000]; - szBuf[0] = '\0'; - _snwprintf(szBuf, NUMCHARS(szBuf), L"PC IP Address[es] are displayed below. You will need one of these to put in the phone app.\n\n"); - - IP_ADAPTER_INFO sfAdapter[255] = {0}; - ULONG cbAdapter = sizeof(sfAdapter); - ULONG ret = GetAdaptersInfo(sfAdapter, &cbAdapter); - int cConnected = 0; - if(ret == NO_ERROR) - { - IP_ADAPTER_INFO* pInfo = &sfAdapter[0]; - while(pInfo) - { - TCHAR szLine[255]; - if(strcmp(pInfo->IpAddressList.IpAddress.String, "0.0.0.0") != 0) - { - _snwprintf(szLine, NUMCHARS(szLine), L"%S - %S\n", pInfo->Description, pInfo->IpAddressList.IpAddress.String); - wcsncat(szBuf,szLine, NUMCHARS(szBuf)); - cConnected++; - } - - pInfo = pInfo->Next; - } - - if(cConnected > 0) - { - MessageBox(NULL, szBuf, L"Ip address info", MB_OK); - return; - } - else - { - int iResult = MessageBox(NULL, L"WifiLapper Pitside cannot find any network devices connected. Please connect to a network and try again.", L"Could not find IP addresses", MB_ABORTRETRYIGNORE | MB_ICONWARNING); - if(iResult == IDABORT) - { - exit(0); - } - else if(iResult == IDRETRY) - { - // just let the loop roll - } - else if(iResult == IDIGNORE) - { - // ok, they just want to get to the app. - return; - } - } - } - } // loop for retrying - } - void InitAxes(set setAvailable) - { - static set setLast; - if(AreSetsEqual(setLast,setAvailable)) return; // nothing to do - - m_sfXAxis.Clear(); - m_sfYAxis.Clear(); - TCHAR szDataChannelName[MAX_PATH]; - for(set::const_iterator i = setAvailable.begin(); i != setAvailable.end(); i++) - { - GetDataChannelName(*i, szDataChannelName, NUMCHARS(szDataChannelName)); - m_sfXAxis.AddString(szDataChannelName,*i); - m_sfYAxis.AddString(szDataChannelName,*i); - } - setLast = setAvailable; - } - void InitBaseWindowPos() - { -#define GET_WINDOWPOS(idc) \ - { \ - WINDOWPLACEMENT wp; \ - wp.length = sizeof(wp); \ - HWND hWnd = GetDlgItem(m_hWnd,idc); \ - GetWindowPlacement(hWnd, &wp); \ - m_baseWindowPos[idc] = wp.rcNormalPosition; \ - } - WINDOWPLACEMENT wp; - wp.length = sizeof(wp); - HWND hWnd = m_hWnd; - GetWindowPlacement(hWnd, &wp); - m_baseWindowPos[IDD_DLGFIRST] = wp.rcNormalPosition; - - GET_WINDOWPOS(IDC_DISPLAY); - GET_WINDOWPOS(IDC_SUBDISPLAY); - GET_WINDOWPOS(IDC_LAPS); - GET_WINDOWPOS(IDC_TRACTIONCIRCLEMAP); - - } - void HandleCtlResize(SIZE sNewSize, int idc, bool fResizeX, bool fResizeY) - { - HWND hwndMainView = GetDlgItem(m_hWnd, idc); - RECT rcBasePos = m_baseWindowPos[idc]; - SIZE sNewCtlSize = {fResizeX ? (sNewSize.cx - rcBasePos.left) : RECT_WIDTH(&rcBasePos), fResizeY ? (sNewSize.cy - rcBasePos.top) : RECT_HEIGHT(&rcBasePos)}; - MoveWindow(hwndMainView, rcBasePos.left, rcBasePos.top, sNewCtlSize.cx, sNewCtlSize.cy, TRUE); - } - void HandleResize(SIZE sNewSize) - { - HandleCtlResize(sNewSize, IDC_DISPLAY, true, true); // main display window - HandleCtlResize(sNewSize, IDC_SUBDISPLAY, false, false); // sub display window - HandleCtlResize(sNewSize, IDC_LAPS, false, true); // lap list - HandleCtlResize(sNewSize, IDC_TRACTIONCIRCLEMAP, false, false); // Traction circle window - } - float fAverage(DATA_CHANNEL eChannel, const IDataChannel* pChannel, float flVal) - { - // This function returns the average value for the data channel across all data points from this lap. - char szAvg[MAX_PATH]; - float sum = 0.0f; - int count; - vector channels = pChannel->GetData(); // get the values for all of the data points - for (count = 0; count < channels.size(); count++) - { - GetChannelValue(eChannel,m_sfLapOpts.eUnitPreference,channels[count].flValue,szAvg,NUMCHARS(szAvg)); - sum = sum + atof(szAvg); - } - if (count != 0) - { - return sum / count; - } - else - { - return sum; - } - } -void UpdateSectors() - { - // Update the Sector Times display - // The idea here is to get the sector positions and iTime from sfLapOpts, then for each highlighted - // Lap run through the Ref Lap Time/Distance array and interpolate the iTime at the equivalent distance - // Coding is similar to TimeSlip + HDC hdcSource; + HDC hdcWindow; + HDC hdcMemDC = NULL; + HBITMAP hbmSource = NULL; + BITMAP bmpSource; - // First, let's make sure that we have a Reference Lap, or let's not perform this - if (m_pReferenceLap != NULL) - { - const int cSectors = 9; // The maximum number of Sectors to display, gated by display area - const int MaxLaps = 7; // Maximum number of laps to display - int w = 0; // String variable counter for Sector display + // Retrieve the handle to a display device context for the client area of the window. + hdcSource = GetDC(NULL); + hdcWindow = GetDC(hWnd); - // Get the list of highlighted lap time ID's - set setSelected = m_sfLapList.GetSelectedItemsData(); - - // Load the CExtendedLap data for the lap list - vector lstLaps = GetLapsToShow(); - - // Get the points from the Ref Lap for computation - const vector& lstRefPoints = m_pReferenceLap->GetPoints(); // For iTime - const IDataChannel* pReferenceDistance = m_pReferenceLap->GetChannel(DATA_CHANNEL_DISTANCE); - - // Strings for building the Sector Times output for each lap - TCHAR szLapString[50][512] = {NULL}; - TCHAR szString[50][512] = {NULL}; - - // Lap Loop - // Now loop through the lap list, compute the sector times and store them in SplitPoints[] - for(vector::iterator i = lstLaps.begin(); i != lstLaps.end(); i++) - { - // Get the data points for this lap, and compare the sector times to the Reference Lap (m_pReferenceLap) - CExtendedLap* pLap = *i; - - // Get the points from the Selected Lap for computation - const vector& lstLapPoints = pLap->GetPoints(); - - pLap->GetString(szLapString[w], NUMCHARS(szLapString)); // Timestamp of this lap, to used to name it - if (_tcslen(szLapString[w]) <= 30) - { - swprintf(szLapString[w], NUMCHARS(szLapString[w]), L"%s\t", szLapString[w]); // Add a TAB mark for formatting - } - else - { - swprintf(szLapString[w], 39, szLapString[w]); // Truncate the Timestamp string for formatting - } - - const IDataChannel* pDistance = pLap->GetChannel(DATA_CHANNEL_DISTANCE); - - int iLapStartTime = lstLapPoints[0].iTime; - - // Sector Loop - // Now loop through the split points and determine lap times for each sector - for(int s = 1; s <= cSectors; s++) - { - // Get the Split Point iTime and it's distance value - const int SectorStartTime = m_sfLapOpts.m_SplitPoints[s].m_sfSectorTime; - const double dSectorDistance = pReferenceDistance->GetValue((int)SectorStartTime); - - // First iTime for the lap array - bool b_SectorFlag = false; - double dLastLapDist = 0; - // Interpolation Loop - // Now go through the lap array and find the 2 points that span the dSectorDistance distance - for (int x = 1; x < lstLapPoints.size(); x++) - { - const int iElapsedTime = lstLapPoints[x].iTime - iLapStartTime; - const double dDistance = pDistance->GetValue(lstLapPoints[x].iTime); - dLastLapDist = pDistance->GetValue(lstLapPoints[x-1].iTime); - - TimePoint2D pLapPoint = lstLapPoints[x]; - // this lap's time at {dDistance} was {iElapsedTime}. - // we now need to estimate what the lap time at {dDistance} was, and then we can get our sector time - const int cLapSize = lstLapPoints.size(); - if(dDistance >= dSectorDistance && dLastLapDist <= dSectorDistance) - { - // we have found two points straddling the distance we're curious about, dSectorDistance - const double dOffset = dSectorDistance - dLastLapDist; // how far into the {dLastRefDist,dRefDist} x axis we are - const double dWidth = dDistance - dLastLapDist; // how far apart {dLastRefDist,dRefDist} are - double dFraction = 0; - if(dWidth != 0) - { - dFraction = dOffset / dWidth; // the fraction that dDistance is between dLastLapDist and dDistance - if(dFraction >= 0.0 && dFraction <= 1.0) - { - const int iLastTime = lstLapPoints[x-1].iTime; - const int iThisTime = lstLapPoints[x].iTime; - const double dEstimatedElapsedTime = dFraction * (iThisTime - iLastTime) + (double)iLastTime; - // this is the estimated time for the previous lap at this position - if(dEstimatedElapsedTime >= 0) - { - float dSectorTime = dEstimatedElapsedTime - (double)iLapStartTime; - // Now that we have computed the Sector Time, let's build the Sector times string - swprintf(szString[w], NUMCHARS(szString[w]), L"%s\t%4.2f", szString[w], dSectorTime/1000); - iLapStartTime = dEstimatedElapsedTime; - dLastLapDist = dSectorDistance; - break; - } - } - } - else - { - const int iLastTime = lstLapPoints[x-1].iTime; - float dSectorTime = iLastTime - (double)iLapStartTime; - // Now that we have computed the Sector Time, let's build the Sector times string - swprintf(szString[w], NUMCHARS(szString[w]), L"%s\t%4.2f", szString[w], dSectorTime/1000); - iLapStartTime = iLastTime; - dLastLapDist = dSectorDistance; - break; - } - } - if (x == lstLapPoints.size()-1) - { - // We've reached the end of the loop. Dump the last point as the last sector time, if other conditions failed - const int iLastTime = lstLapPoints[lstLapPoints.size()-1].iTime; - float dSectorTime = iLastTime - (double)iLapStartTime; - // Now that we have computed the Sector Time, let's build the Sector times string - swprintf(szString[w], NUMCHARS(szString[w]), L"%s\t%4.2f", szString[w], dSectorTime/1000); - iLapStartTime = iLastTime; - dLastLapDist = dSectorDistance; - break; - } - } - // End Interpolation Loop - } - // End Sector Loop - - // Now that we have computed the Sector Time, let's Display them -/* if (w == lstLaps.size() - 1 && m_fShowReferenceLap) - { - swprintf(szLapString[w], NUMCHARS(szLapString[w]), L"\t\tRef Lap: \t%s", szString[w]); - SendMessage(m_sfLapOpts.hWndLap[w], WM_SETTEXT, 0, (LPARAM)szLapString[w]); - } - else -*/ { - swprintf(szLapString[w], NUMCHARS(szLapString[w]), L"%s %s", szLapString[w], szString[w]); - SendMessage(m_sfLapOpts.hWndLap[w], WM_SETTEXT, 0, (LPARAM)szLapString[w]); - } - // Increment "w" counter and do the next lap - w++; - if (w >= MaxLaps) break; // Stop building these if we already have as many as we need. - } - // Clean up any old lap sector times if user chose fewer laps to display - for (int x = w; x < MaxLaps; x++) - { - swprintf(szLapString[x], NUMCHARS(szLapString[x]), L"Lap %i:", x + 1); - SendMessage(m_sfLapOpts.hWndLap[x], WM_SETTEXT, 0, (LPARAM)szLapString[x]); - } + // Create a compatible DC which is used in a BitBlt from the window DC + hdcMemDC = CreateCompatibleDC(hdcWindow); - // End Lap Loop - } - } -void UpdateValues() - { - // Update the data channels that are being displayed as values - // List of highlighted laps - set setSelectedData = m_sfLapList.GetSelectedItemsData(); - if(setSelectedData.size() > 0) - { - const int cLabels = 5; // The maximum number of Value Data channels to display, gated by display area - bool m_Warning = false; // Flag for showing dialog of Value display to indicate statistics are outside of bounds - TCHAR m_szYString[512] = {NULL}; - TCHAR m_szWarningChannel[MAX_PATH] = {NULL}; - int w=0; // String variable counter for Vaue display - TCHAR szLabel[cLabels][MAX_PATH] = {NULL}; - // Loop through the selected Y-axis data channels for this lap - for(int x = 0; x < this->m_lstYChannels.size() && x < 49; x++) - { - const DATA_CHANNEL eChannel = m_lstYChannels[x]; - if(!eChannel /*|| !eChannel->IsValid()*/) continue; - float flMin, flMax, flAvg, flMinTemp, flMaxTemp; - // First check if this data channel is one to be displayed as a Value (false) or Graph (true) - for (int u = 0; u < sizeof m_lstYChannels; u++) - { - if (m_lstYChannels[x] == m_sfLapOpts.m_PlotPrefs[u].iDataChannel && m_sfLapOpts.m_PlotPrefs[u].iPlotView == true) + if(!hdcMemDC) { - break; // Data channel is requested to be displayed as a graph, do nothing here + MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK); + break; } - else if (m_lstYChannels[x] == m_sfLapOpts.m_PlotPrefs[u].iDataChannel && m_sfLapOpts.m_PlotPrefs[u].iPlotView == false) + + // Get the client area for size calculation + RECT rcClient; + // Get the windows coordinates for the Window, hWnd + ::GetWindowRect (hWnd,&rcClient); + // Get the dimensions of the target image handle, hWnd + RECT rc; + ::GetWindowRect (hWnd,&rc); + //This is the best stretch mode + SetStretchBltMode(hdcWindow,HALFTONE); + + //The source DC is the current window and the destination DC is the current window (HWND) + if(!StretchBlt(hdcWindow, + 0,0, + rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, + hdcSource, + rc.left+8, rc.top+50, // Adjustments to remove menu duplicate + rc.right-rc.left, rc.bottom-rc.top, + SRCCOPY)) { - // Let's get the statistical values for this channel for display - // go through all the laps we have selected to figure out min/max - flMin = 1e30; - flMax = -1e30; - float flVal; - for(set::const_iterator i = setSelectedData.begin(); i != setSelectedData.end(); i++) + MessageBox(hWnd, L"StretchBlt has failed",L"Failed", MB_OK); + break; + } + + // Create a compatible bitmap from the Window DC + hbmSource = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top); + + if(!hbmSource) + { + MessageBox(hWnd, L"CreateCompatibleBitmap Failed",L"Failed", MB_OK); + break; + } + + // Select the compatible bitmap into the compatible memory DC. + SelectObject(hdcMemDC,hbmSource); + + // Bit block transfer into our compatible memory DC. + if(!BitBlt(hdcMemDC, + 0,0, + rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, + hdcSource, + rcClient.left,rcClient.top, + SRCCOPY)) + { + MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK); + break; + } + + // Get the BITMAP from the HBITMAP + GetObject(hbmSource,sizeof(BITMAP),&bmpSource); + + BITMAPFILEHEADER bmfHeader = {0}; + BITMAPINFOHEADER bi = {0}; + + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = bmpSource.bmWidth; + bi.biHeight = bmpSource.bmHeight; + bi.biPlanes = 1; + bi.biBitCount = 32; + bi.biCompression = BI_RGB; + bi.biSizeImage = 0; + bi.biXPelsPerMeter = 0; + bi.biYPelsPerMeter = 0; + bi.biClrUsed = 0; + bi.biClrImportant = 0; + + DWORD dwBmpSize = ((bmpSource.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpSource.bmHeight; + + // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that + // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc + // have greater overhead than HeapAlloc. + HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); + char *lpbitmap = (char *)GlobalLock(hDIB); + + // Gets the "bits" from the bitmap and copies them into a buffer + // which is pointed to by lpbitmap. + GetDIBits(hdcWindow, hbmSource, 0, + (UINT)bmpSource.bmHeight, + lpbitmap, + (BITMAPINFO *)&bi, DIB_RGB_COLORS); + + // If request is to save or print an image file, request name and save it. + if (SaveFlag || PrintFlag) + { + + // Let's get the output file name from the user. + TCHAR szTempPath[MAX_PATH], szTempName[MAX_PATH]; + TCHAR szFileName[MAX_PATH] = {NULL}; + if (PrintFlag) { - CExtendedLap* pLap = (CExtendedLap*)*i; - const IDataChannel* pChannel = pLap->GetChannel(eChannel); - if (pChannel) // Check if pointer is valid - { - flVal = pChannel->GetValue(m_mapLapHighlightTimes[pLap]); - flMin = pChannel->GetMin(); - flMax = pChannel->GetMax(); - // 951turbo: do more math here like averages, median, etc. - flAvg = fAverage(eChannel, pChannel, flVal); - // See if the Minimum or Maximum are outside of the PlotPrefs setpoints -////////////////////////////////////////// - // Adding transformation functions here for Y - if (m_sfLapOpts.m_PlotPrefs[u].iTransformYesNo == true) - { - if (m_sfLapOpts.m_PlotPrefs[u].fTransBValue < 0) - { - flAvg = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flAvg * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flAvg * flAvg * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; - flMaxTemp = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flMin * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flMin * flMin * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; - flMinTemp = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flMax * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flMax * flMax * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; - } - else - { - flAvg = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flAvg * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flAvg * flAvg * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; - flMinTemp = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flMin * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flMin * flMin * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; - flMaxTemp = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flMax * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flMax * flMax * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; - } - flMin = flMinTemp; - flMax = flMaxTemp; - } -////////////////////////////////////////// - if (flMax > m_sfLapOpts.m_PlotPrefs[u].fMaxValue || flMin < m_sfLapOpts.m_PlotPrefs[u].fMinValue) + GetTempPath(NUMCHARS(szTempPath),szTempPath); // Get the TEMP folder path + swprintf(szTempName,NUMCHARS(szTempName), L"%sTmpFile.bmp", szTempPath); + } + else + { + + wcscat(szFileName,L"Picture.jpg"); + while (true) { - m_Warning = true; // An alarm has been triggered! Save the channel name and post a warning dialog. - GetDataChannelName(eChannel,m_szWarningChannel,NUMCHARS(m_szWarningChannel)); - // Build the failing channels string for output - swprintf(m_szYString,NUMCHARS(m_szYString),L"%s\n%s",m_szYString, m_szWarningChannel); + if(ArtGetSaveFileName(hWnd, L"Choose Filename to save as a JPEG File.", szFileName, NUMCHARS(szFileName),L"JPG Files (*.jpg)\0*.JPG\0\0")) + { + // let's make sure there's a .jpg suffix on that bugger. + if(!str_ends_with(szFileName,L".jpg") && !str_ends_with(szFileName,L".JPG")) + { + wcsncat(szFileName,L".jpg", NUMCHARS(szFileName)); + } + const bool fFileIsNew = !DoesFileExist(szFileName); + if(fFileIsNew) + { + break; // Exit loop, as file name is valid and new + } + else + { + DWORD dwRet = MessageBox(NULL,L"A file already exists with that name.\n\nAre you sure you want to overwrite it?",L"WARNING", MB_APPLMODAL | MB_ICONWARNING | MB_YESNO | MB_TOPMOST | MB_DEFBUTTON2); + if (dwRet == IDYES) + { + break; // User wants to overwrite file, so exit loop and proceed + } + } + } + else + { + return 0; // User cancelled the save operation, so leave subroutine + } } - } - else - { - flVal=0.0f; - flMin=0.0f; - flMax=0.0f; - flAvg=0.0f; - } + + // Create a temporary BMP file, this is where we will save the screen capture. + swprintf(szTempName, NUMCHARS(szTempName), L"%s.bmp", szFileName); } - // Now assign these values to the Data Value variable for display - TCHAR szChannelName[MAX_PATH]; - GetDataChannelName(eChannel,szChannelName,NUMCHARS(szChannelName)); + // Add the size of the headers to the size of the bitmap to get the total file size + DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + + //Offset to where the actual bitmap bits start. + bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); + + //Size of the file + bmfHeader.bfSize = dwSizeofDIB; + + //bfType must always be BM for Bitmaps + bmfHeader.bfType = 0x4D42; //BM - char szMin[MAX_PATH]; - char szMax[MAX_PATH]; - GetChannelValue(eChannel,m_sfLapOpts.eUnitPreference,flMin,szMin,NUMCHARS(szMin)); - GetChannelValue(eChannel,m_sfLapOpts.eUnitPreference,flMax,szMax,NUMCHARS(szMax)); - // Now assemble the string to display (max of 5) - if (w < cLabels) + // Open a handle to the TEMP BMP file and write the DIB to it + HANDLE hFile = CreateFile(szTempName, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + + DWORD dwBytesWritten = 0; + WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); + WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); + WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL); + + //Close the handle for the file that was created + CloseHandle(hFile); + + //Unlock and Free the DIB from the heap +// GlobalUnlock(hDIB); +// GlobalFree(hDIB); + + // Now let's convert this Bitmap into a JPEG file, if the user wants to save it. + if (SaveFlag) { - swprintf(szLabel[w],NUMCHARS(szLabel[w]),L"%s: Min: %S, Max: %S, Avg: %3.1f",szChannelName,szMin,szMax,flAvg); - w++; // Increment Value string counter + // Load the BMP from a temporary file on the disk, and convert it + jpge::params params; + params.m_no_chroma_discrim_flag = 0; + params.m_quality = 95; + params.m_subsampling = jpge::subsampling_t::H2V2; + params.m_two_pass_flag = 0; + + wstring strW(szFileName); // unicode -> const char* conversion + string strA(strW.begin(),strW.end()); // unicode -> const char* conversion + + jpge::compress_image_to_jpeg_file(strA.c_str(),bi.biWidth,-bi.biHeight,4,(const jpge::uint8*)lpbitmap,params); + + DeleteFile(szTempName); // Remove the TEMP file + //Unlock and Free the DIB from the heap + GlobalUnlock(hDIB); + GlobalFree(hDIB); + } + else if (PrintFlag) + { + //Unlock and Free the DIB from the heap + GlobalUnlock(hDIB); + GlobalFree(hDIB); + + //////////////////////////////////////////////////////////////////////////////// + cxsize=0, cxpage=0; + cysize=0, cypage=0; + PAINTSTRUCT ps; + + // Let's get the Bitmap image for printing + { + ZeroMemory(&hBitmap, sizeof(HBITMAP)); + + hBitmap = (HBITMAP)LoadImage(NULL,szTempName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE|LR_VGACOLOR); + if(hBitmap) + { + cxpage = GetDeviceCaps (hdc, HORZRES); + cypage = GetDeviceCaps (hdc, VERTRES); + GetObject(hBitmap,sizeof(BITMAP),&bitmap); + bxWidth = bitmap.bmWidth; + bxHeight = bitmap.bmHeight; + } + + // Let's paint the image into a Device Context + hdc = BeginPaint(hWnd, &ps); + hdcMem = CreateCompatibleDC(hdc); + SelectObject(hdcMem, hBitmap); + SetMapMode (hdc, MM_ISOTROPIC); + SetWindowExtEx(hdc, cxpage,cypage, NULL); + SetViewportExtEx(hdc, cxsize, cysize,NULL); + SetViewportOrgEx(hdc, 0, 0, NULL); + SetStretchBltMode(hdc,COLORONCOLOR); + StretchBlt(hdc, 0, 0, bxWidth, bxHeight, hdcMem, 0, 0,bxWidth,bxHeight, SRCCOPY); + + EndPaint(hWnd, &ps); + DeleteDC(hdcMem); + + // Now let's print the loaded image + DOCINFO di= { sizeof (DOCINFO), TEXT ("Printing Picture...")}; + HDC prn = NULL; + // Open up the standard printer dialog and get our printer DC + prn = GetPrinterDC(hWnd); + + // Let's set up the printer for Landscape Mode printing +// TCHAR pDevice[MAX_PATH]; +// swprintf(pDevice, NUMCHARS(pDevice), L"PrinterName, Job 0001"); +// GetLandscapeDevMode(hWnd, pDevice, (HANDLE)prn); + + if (prn) + { + cxpage = GetDeviceCaps (prn, HORZRES); + cypage = GetDeviceCaps (prn, VERTRES); + hdcMem = CreateCompatibleDC(prn); + HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hBitmap); + + StartDoc (prn, &di); + StartPage (prn) ; + SetMapMode (prn, MM_ISOTROPIC); + SetWindowExtEx(prn, cxpage,cypage, NULL); + SetViewportExtEx(prn, cxpage, cypage,NULL); + + SetViewportOrgEx(prn, 0, 0, NULL); + StretchBlt(prn, 0, 0, cxpage, cypage, hdcMem, 0, 0,bxWidth,bxHeight, SRCCOPY); + EndPage (prn); + EndDoc(prn); + DeleteDC(prn); + SelectObject(hdcMem, hbmOld); + DeleteDC(hdcMem); + } + DeleteFile(szTempName); + //////////////////////////////////////////////////////////////////////////////// + } } - break; } else { - } - } - } - // Display the Data Value Channels - for (int z = 0; z < cLabels; z++) - { - HWND hWndLabel = GetDlgItem(m_hWnd, IDC_VALUE_CHANNEL1 + z); - hdc = GetDC(hWndLabel); - - SetBkMode(hdc,TRANSPARENT); - SetTextColor(hdc,RGB(255,0,0)); - //GetSysColorBrush(GetSysColor(COLOR_WINDOW)); - CreateSolidBrush(RGB(255,255,255)); - - //SetTextColor( hdc, RGB(255, 0, 0) ); - //SetBkColor(hdc, RGB(222,231,249)); - SendMessage(hWndLabel, WM_SETTEXT, 0, (LPARAM)szLabel[z]); - } - if (m_Warning) // Pop up dialog saying the alarm has been triggered - { - static bool fWarnedOnce = false; - if(!fWarnedOnce) - { - // Display a warning dialog box about an alarm being triggered. - fWarnedOnce = true; - WARNING_RESULT sfResult; - CWarningDlg dlgWarning(&sfResult, m_szYString); - ArtShowDialog(&dlgWarning); - fWarnedOnce = false; - } - } - } - } - void UpdateDisplays() - { - m_sfLapPainter.Refresh(); - m_sfSubDisplay.Refresh(); - if (m_sfLapOpts.bTractionCircle) - { - m_sfTractionDisplay.Refresh(); - } - } - void CheckMenuHelper(HMENU hMainMenu, int id, bool fChecked) - { - DWORD dwFlags = fChecked ? (MF_BYCOMMAND | MF_CHECKED) : (MF_BYCOMMAND | MF_UNCHECKED); - DWORD dwRet = CheckMenuItem(hMainMenu, id, dwFlags); - DASSERT(dwRet != -1); - } - void UpdateMenus() - { - HMENU hWndMenu = GetMenu(m_hWnd); - HMENU hSubMenu = GetSubMenu(hWndMenu, 2); - - CheckMenuHelper(hSubMenu, ID_OPTIONS_KMH, m_sfLapOpts.eUnitPreference == UNIT_PREFERENCE_KMH); - CheckMenuHelper(hSubMenu, ID_OPTIONS_MPH, m_sfLapOpts.eUnitPreference == UNIT_PREFERENCE_MPH); - CheckMenuHelper(hSubMenu, ID_OPTIONS_MS, m_sfLapOpts.eUnitPreference == UNIT_PREFERENCE_MS); - CheckMenuHelper(hSubMenu, ID_OPTIONS_TRACTIONCIRCLE, m_sfLapOpts.bTractionCircle); - CheckMenuHelper(hSubMenu, ID_OPTIONS_SHOWBESTS, m_fShowBests); - CheckMenuHelper(hSubMenu, ID_OPTIONS_SHOWDRIVERBESTS, m_fShowDriverBests); - CheckMenuHelper(hSubMenu, ID_OPTIONS_SHOWREFERENCELAP, m_fShowReferenceLap); - CheckMenuHelper(hSubMenu, ID_OPTIONS_DRAWLINES, m_sfLapOpts.fDrawLines); - CheckMenuHelper(hSubMenu, ID_OPTIONS_BACKGROUND, m_sfLapOpts.fColorScheme); - CheckMenuHelper(hSubMenu, ID_OPTIONS_IOIO5VSCALE, m_sfLapOpts.fIOIOHardcoded); - CheckMenuHelper(hSubMenu, ID_OPTIONS_ELAPSEDTIME, m_sfLapOpts.fElapsedTime); - } + // User wants to copy image to Clipboard. - vector GetSortedLaps(LAPSORTSTYLE eSortStyle) + //Unlock and Free the DIB from the heap + GlobalUnlock(hDIB); + GlobalFree(hDIB); + + // Add the size of the headers to the size of the bitmap to get the total DIB size + DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + + //Offset to where the actual bitmap bits start. + bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); + + //Size of the file + bmfHeader.bfSize = dwSizeofDIB; + + //bfType must always be BM for Bitmaps + bmfHeader.bfType = 0x4D42; //BM + + // lpbitmap is the pointer to the BMP byte array + { + char* bitmapBuffer = lpbitmap; + size_t buflen = dwSizeofDIB; +// size_t buflen = dwBmpSize; + + copyBitmapToClipboard(bitmapBuffer, buflen); + +// DWORD dwBytesWritten = 0; +// WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); +// WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); +// WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL); + + } + } + //Unlock and Free the DIB from the heap + GlobalUnlock(hDIB); + GlobalFree(hDIB); + DeleteObject(hbmSource); + DeleteObject(hdcMemDC); + ReleaseDC(NULL,hdcSource); + ReleaseDC(hWnd,hdcWindow); + UpdateUI(UPDATE_ALL); +// InitAxes(setSelectedChannels); + return TRUE; + } + case ID_FILE_EXIT: + { + DestroyWindow(hWnd); + break; + } + case ID_TIMINGSCORING: + { + // Let's set up for displaying the T&S page + int m_RaceId[50] = {NULL}; + // Show the race-selection dialog and let the User pick which ones to use on T&S page + static bool bSelectSessions; + if (!bSelectSessions) // Prevent duplicate windows + { + bSelectSessions = true; + SELECTSESSIONS_RESULT sfResult; + CDlgSelectSessions dlgRace(g_pLapDB, &sfResult); + ArtShowDialog(&dlgRace); + if( !sfResult.fCancelled ) // Allow the user to show the menu and start a race, even if no data has been collected from the racers yet + { + // Now display the T&S page and pass these RaceID's to this class + TS_RESULT ts_sfResult; + CDlgTimingScoring dlgTS(g_pLapDB, &ts_sfResult, m_szPath, &sfResult); + ArtShowDialog(&dlgTS); + } + bSelectSessions = false; + } + return TRUE; + } + case ID_DATA_OPENDB: + { + TCHAR szFilename[MAX_PATH]; + if(ArtGetOpenFileName(hWnd, L"Choose WFLP file", szFilename, NUMCHARS(szFilename),L"WifiLapper Files (*.wflp)\0*.WFLP\0\0")) + { + if(g_pLapDB->Init(szFilename)) + { + _snwprintf(m_szPath, NUMCHARS(m_szPath), szFilename); + RACESELECT_RESULT sfResult; + + // Zero out the Race ID's before selecting them + for (int z = 0; z < 50; z++) + { + m_iRaceId[z] = -1; + sfResult.iRaceId[z] = -1; + } + + CRaceSelectDlg dlgRace(g_pLapDB, &sfResult); + ArtShowDialog(&dlgRace); + + if(!sfResult.fCancelled) + { + for (int z = 0; z < 50; z++) + { + m_iRaceId[z] = sfResult.iRaceId[z]; // Load all of the race sessions chosen + } + ClearUILaps(); + LoadLaps(g_pLapDB); + UpdateUI(UPDATE_ALL); + // Let's reset the timer + tmLast = timeGetTime(); // Save last time lap was received + + // Find all of the Names of the selected Race Sessions for addition to title bar + vector lstRaces = g_pLapDB->GetRaces(); + TCHAR lstSessions[MAX_PATH] = {NULL}; + for(int x = 0;x < lstRaces.size(); x++) + { + for (int z = 0; z < 50; z++) + { + if ( m_iRaceId[z] == lstRaces[x].raceId ) + { + _snwprintf(lstSessions, NUMCHARS(lstSessions), L"%s | %s", lstSessions, lstRaces[x].strName.c_str()); + break; + } + } + } + TCHAR szTemp[MAX_PATH] = {NULL}; + _snwprintf(szTemp, NUMCHARS(szTemp), L"Pitside - %s%s", m_szPath, lstSessions); + SetWindowText(hWnd, szTemp); // Change the title bar to show the file name opened + } + } + } + return TRUE; + } + case ID_DATA_DASHWARE: // Save the data to a .CSV file + { + set setSelectedData = m_sfLapList.GetSelectedItemsData3(); + if(setSelectedData.size() > 0) + { + TCHAR szFilename[MAX_PATH] = {NULL}; + wcscat(szFilename,L"Export.csv"); + while (true) + { + if(ArtGetSaveFileName(hWnd, L"Choose Output file", szFilename, NUMCHARS(szFilename),L"CSV Files (*.csv)\0*.CSV\0\0")) + { + // let's make sure there's a .csv suffix on that bugger. + if(!str_ends_with(szFilename,L".csv") && !str_ends_with(szFilename,L".CSV")) + { + wcsncat(szFilename,L".csv", NUMCHARS(szFilename)); + } + const bool fFileIsNew = !DoesFileExist(szFilename); + if(fFileIsNew) + { + break; // Exit loop, as file name is valid and new + } + else + { + DWORD dwRet = MessageBox(NULL,L"A file already exists with that name.\n\nAre you sure you want to overwrite it?",L"WARNING", MB_APPLMODAL | MB_ICONWARNING | MB_YESNO | MB_TOPMOST | MB_DEFBUTTON2); + if (dwRet == IDYES) + { + break; // User wants to overwrite file, so exit loop and proceed + } + } + } + else + { + return 0; // User cancelled the save operation, so leave subroutine + } + } + + // Display the "Working...." dialog, as this is going to take some time. + DLGPROC working = NULL; + HWND hwndGoto = NULL; // Window handle of dialog box + if (!IsWindow(hwndGoto)) + { + hwndGoto = CreateDialog(NULL, MAKEINTRESOURCE (IDD_PROGRESS), hWnd, working); + ShowWindow(hwndGoto, SW_SHOW); + } + + vector lstLaps; + vector lstLaps1 = GetLapsToShow(); + for(set::iterator i = setSelectedData.begin(); i != setSelectedData.end(); i++) + { + CExtendedLap* pLap = (CExtendedLap*)*i; + lstLaps.push_back(pLap->GetLap()); + } + DashWare::SaveToDashware(szFilename, lstLaps, lstLaps1); // lstLaps does not have the reference lap in it, lstLaps1 may have it + DestroyWindow(hwndGoto); // Close the "Working..." dialog + hwndGoto = NULL; + } + else + { + MessageBox(NULL,L"Please Select Laps",L"You must select some laps first!",MB_OK | MB_ICONWARNING); + } + return TRUE; + } + case IDC_DISPLAYTYPE_LINE: + { + switch(HIWORD(wParam)) + { + case BN_CLICKED: + m_eLapDisplayStyle = LAPDISPLAYSTYLE_MAP; + UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD); + break; + } + return TRUE; + } +/* case IDC_DISPLAYTYPE_RECEPTION: + { + switch(HIWORD(wParam)) + { + case BN_CLICKED: + m_eLapDisplayStyle = LAPDISPLAYSTYLE_RECEPTION; + UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); + break; + } + return TRUE; + } +*/ case IDC_DISPLAYTYPE_PLOT: + { + switch(HIWORD(wParam)) + { + case BN_CLICKED: + m_eLapDisplayStyle = LAPDISPLAYSTYLE_PLOT; + UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD); + break; + } + return TRUE; + } + case IDC_SETREFERENCE: + { + // they want to set a given lap as a reference lap + set setSelected = m_sfLapList.GetSelectedItemsData3(); + if(setSelected.size() == 1) + { + CExtendedLap* pNewRefLap = (CExtendedLap*)*(setSelected.begin()); + pNewRefLap->ComputeDistances(NULL, g_pLapDB); + for(map::iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) + { + if(i->second != pNewRefLap) + { + i->second->ComputeDistances(pNewRefLap, g_pLapDB); // tell this lap to recompute using pLap as the reference lap + } + } + m_pReferenceLap = pNewRefLap; + } + else + { + // what's going on? This should've been disabled + } + UpdateUI(UPDATE_MAP | UPDATE_DASHBOARD | UPDATE_VALUES); + return TRUE; + } + case IDC_LIVEDATA: + { + // Let's toggle all live data collection threads on/off to allow for lap analysis + switch(HIWORD(wParam)) + { + case BN_CLICKED: + { + b_Button_LiveData = !b_Button_LiveData; + m_sfLapOpts.b_Button_LiveData = b_Button_LiveData; + UpdateUI(UPDATE_DASHBOARD); // Redraw the laplist and buttons + break; + } + } + return TRUE; + } + case IDC_SETDRIVER: // they want to set the driver of the selected laps + { + switch(HIWORD(wParam)) + { + case BN_CLICKED: + ApplyDriverNameToSelectedLaps(::g_pLapDB); + UpdateUI(UPDATE_LIST | UPDATE_DASHBOARD); // Redraw the laplist and buttons + break; + } + return TRUE; + } + case IDC_CLEARCOMMENT: // This button clears the comment field + { + switch(HIWORD(wParam)) + { + case BN_CLICKED: + m_szCommentText[0] = '\0'; + SendMessage(GetDlgItem(m_hWnd, IDC_COMMENTTEXT), WM_SETTEXT, NUMCHARS(m_szCommentText), (LPARAM)m_szCommentText); +// UpdateUI(UPDATE_LIST | UPDATE_DASHBOARD); + break; + } + return TRUE; + } + case IDC_COMMENTTEXT: + { + switch(HIWORD(wParam)) + { + case EN_CHANGE: + { + SendMessage(GetDlgItem(m_hWnd, IDC_COMMENTTEXT), WM_GETTEXT, NUMCHARS(m_szCommentText), (LPARAM)m_szCommentText); +// UpdateUI(UPDATE_LIST | UPDATE_DASHBOARD); + break; + } + } + return TRUE; + } + } // end switch for finding out what control WM_COMMAND hit + break; // break out of WM_COMMAND handling + } // End of COMMAND loop + case WM_UPDATEUI: + { + DWORD dwCurrentUpdate = m_fdwUpdateNeeded; + UpdateUI_Internal(dwCurrentUpdate); + m_fdwUpdateNeeded &= ~dwCurrentUpdate; + return TRUE; + } + case WM_NOTIFYUPDATE: + { + switch(wParam) + { + case NOTIFY_NEEDRECVCONFIG: + { + // a lap has been received, but the database isn't set up to receive (aka it's pointing at a high-quality race). + // let's tell the user about it and ask them for input. + static bool fWarnedOnce = false; + if(!fWarnedOnce) + { + fWarnedOnce = true; + MessageBox(NULL,L"You just received a lap from a car, but you're looking at old data. Hit data->'new race session' or else Pitside will keep ignoring it",L"Not ready to receive",0); + } + return TRUE; + } + case NOTIFY_NEWLAP: + { + ILapReceiver* pLapDB = (ILapReceiver*)lParam; + int iLastRaceId = pLapDB->GetLastReceivedRaceId(); + if(m_iRaceId[0] < 0 || pLapDB->GetLapCount(m_iRaceId[0]) <= 0 || // if we don't have a race or our current race has no laps (aka sucks) + (pLapDB->IsActivelyReceiving(iLastRaceId) && !pLapDB->IsActivelyReceiving(m_iRaceId[0]))) // or if the new race ID is receiving and the current race ID isn't... + { + m_iRaceId[0] = pLapDB->GetLastReceivedRaceId(); // since we just got told there's a new lap, there must be a last-received-race + ClearUILaps(); + LoadLaps(g_pLapDB); + UpdateUI(UPDATE_ALL); + } + else + { + LoadLaps((ILapReceiver*)lParam); + UpdateUI(UPDATE_ADD2LIST); // Add the recently received lap to the laplist window + } + // Just loaded a new lap. Let's reset the timer + tmLast = timeGetTime(); // Save last time lap was received + return TRUE; + } + case NOTIFY_NEWDATABASE: + { + // a new database has shown up! + + // first, check if the user cares... + DWORD dwRet = MessageBox(NULL,L"A new database has been sent from a phone. Do you want to load it?",L"New database",MB_YESNO); + if(dwRet == IDYES) + { + LPCTSTR lpszFilename = (LPCTSTR)lParam; + if(g_pLapDB->Init(lpszFilename)) + { + RACESELECT_RESULT sfResult; + + // Zero out the Race ID's before selecting them + for (int z = 0; z < 50; z++) + { + m_iRaceId[z] = -1; + sfResult.iRaceId[z] = -1; + } + + CRaceSelectDlg dlgRace(g_pLapDB, &sfResult); + ArtShowDialog(&dlgRace); + if(!sfResult.fCancelled) + { + for (int z = 0; z < 50; z++) + { + m_iRaceId[z] = sfResult.iRaceId[z]; // Load all of the race sessions chosen + } + + ClearUILaps(); + LoadLaps(g_pLapDB); + UpdateUI(UPDATE_ALL); + } + } + // Let's reset the timer + tmLast = timeGetTime(); // Save last time lap was received + } + return TRUE; + + } + case NOTIFY_NEWNETSTATUS: + { + ILapReceiver* pLaps = (ILapReceiver*)lParam; + SendMessage(m_hWnd, WM_SETTEXT, 0, (LPARAM)pLaps->GetNetStatus(NETSTATUS_STATUS)); + + TCHAR szTemp[512]; +// HWND hWndIp = GetDlgItem(m_hWnd, IDC_CURRENTIP); +// swprintf(szTemp, NUMCHARS(szTemp), L"PC: %s", pLaps->GetNetStatus(NETSTATUS_THISIP)); +// SendMessage(hWndIp, WM_SETTEXT, 0, (LPARAM)szTemp); + + HWND hWndRemoteIp = GetDlgItem(m_hWnd, IDC_CURRENTREMOTEIP); + swprintf(szTemp, NUMCHARS(szTemp), L"Phone: %s", pLaps->GetNetStatus(NETSTATUS_REMOTEIP)); + SendMessage(hWndRemoteIp, WM_SETTEXT, 0, (LPARAM)szTemp); + return TRUE; + } + case NOTIFY_NEWMSGDATA: + { + CMsgThread* pThd = (CMsgThread*)lParam; + pThd->GetStatusMessage(m_szMessageStatus, NUMCHARS(m_szMessageStatus)); + UpdateUI(UPDATE_DASHBOARD); + return TRUE; + } + } + + return 0; + } + case WM_RBUTTONUP: + { + m_sfLapOpts.flWindowShiftX = 0; + m_sfLapOpts.flWindowShiftY = 0; + m_sfLapOpts.iZoomLevels = 0; + UpdateUI(UPDATE_MAP); + return TRUE; + } + case WM_PAINT: + { + UpdateDisplays(); + return FALSE; + } + case WM_SIZE: + { + SIZE sNewSize; + sNewSize.cx = LOWORD(lParam); + sNewSize.cy = HIWORD(lParam); + HandleResize(sNewSize); + return TRUE; + } + } + + return FALSE; +} + DWORD GetDlgId() const {return IDD_DLGFIRST;} + + const static DWORD UPDATE_MAP = 0x1; + const static DWORD UPDATE_LIST = 0x2; + const static DWORD UPDATE_DASHBOARD = 0x4; + const static DWORD UPDATE_MENU = 0x8; + const static DWORD UPDATE_VALUES = 0x10; + const static DWORD UPDATE_TRACTIONCIRCLE = 0x20; + const static DWORD UPDATE_ALLDATA = 0x40; + + const static DWORD UPDATE_ALL = 0xffff; + const static DWORD UPDATE_ADD2LIST = 0x10000; + + // Pull in PlotPrefs array as well as lines vs. dots and Painting color scheme settings from Settings.txt file + void SetDisplayOptions(const LAPSUPPLIEROPTIONS& lapOpts) { - vector lstLaps; - for(map::iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) + m_sfLapOpts = lapOpts; + } + void SetDBPath(const TCHAR szPath[MAX_PATH]) + { + _snwprintf(m_szPath, NUMCHARS(m_szPath), szPath); + } + + void UpdateUI(DWORD fdwUpdateFlags) + { + m_fdwUpdateNeeded|= fdwUpdateFlags; + PostMessage(m_hWnd,WM_UPDATEUI,0,0); + } + + + void UpdateUI_Internal(DWORD fdwUpdateFlags) + { + set setSelectedData = m_sfLapList.GetSelectedItemsData3(); + vector laps = GetSortedLaps(m_sfLapOpts.eSortPreference); // translates our m_mapLaps into a vector sorted by time + // do some memory cleanup + for(int x = 0;x < laps.size(); x++) + { + if(setSelectedData.find((LPARAM)laps[x]) != setSelectedData.end() || laps[x] == m_pReferenceLap) + { + // this lap is still selected, as it is in the set of selected items + } + else + { + // this lap is not selected. we should compact it so that it doesn't gobble memory. + laps[x]->Compact(); + } + } + + if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_LIST)) // rebuild the laplist from scratch { - lstLaps.push_back(i->second); + m_sfLapList.Clear(); + for(int x = 0;x < laps.size(); x++) + { + vector lstStrings; + laps[x]->GetStrings(lstStrings); + m_sfLapList.AddStrings(lstStrings, (LPARAM)laps[x]); + } + + m_sfLapList.SetSelectedData(setSelectedData); + if(laps.size() > 0) + { + m_sfLapList.MakeVisible((LPARAM)laps[laps.size()-1]); // Always set the last lap as visible in the Lap List + } } - switch(eSortStyle) + + if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_ADD2LIST)) { - case SORTSTYLE_BYTIMEOFRACE: - sort(lstLaps.begin(),lstLaps.end(), CExtendedLap_SortByTime); - break; - case SORTSTYLE_BYLAPTIME: - sort(lstLaps.begin(),lstLaps.end(), CExtendedLap_SortByLapTime); - break; + int iLapId; + int x; + const ILap *iLap; + + // Loop through the list of laps to add, making sure avoid duplicates. Find the row to add it + while( m_sfLapList.GetCount() < laps.size() && (iLap = g_pLapDB->GetLastLap()) != NULL ) { + iLapId = iLap->GetLapId(); + + // Find which row this lap needs to appear + for(x = 0;x < laps.size(); x++) { + if( laps[x]->GetLap()->GetLapId() == iLapId ) break; + } + if(x < laps.size()) + { + // x is the index which matches our most recent lap. We need to insert this one into m_sfLapList + vector lstStrings; + laps[x]->GetStrings(lstStrings); + m_sfLapList.InsertStrings(lstStrings, (LPARAM)laps[x], x); + m_sfLapList.MakeVisible((LPARAM)laps[x]); // Always set the last lap as visible in the Lap List + } + else + DASSERT(1);// we didn't find the lap ID from the list of laps to add in the laps vector !! + } + m_sfLapList.SetSelectedData(setSelectedData); } - return lstLaps; - } - - void LoadLaps(ILapReceiver* pReceiver) - { - int z_iRaceId = 0; - for (int z = 0; z < 50; z++) - { - if (m_iRaceId[z] <= 0) break; // Only load the valid Race Id's - z_iRaceId = m_iRaceId[z]; - vector laps = pReceiver->GetLaps(z_iRaceId); - for(int x = 0;x < laps.size(); x++) - { - const ILap* pLap = laps[x]; - // let's see if we already have this lap - if(m_mapLaps.count(pLap->GetLapId()) != 0) - { - // we've already got this lap. THere is nothing to be added from this lap - ((ILap*)pLap)->Free(); - laps[x] = NULL; - } - else - { - // we don't have this lap yet, so let's put it in - CExtendedLap* pNewLap = new CExtendedLap(pLap, m_pReferenceLap, pReceiver, true); - if(m_pReferenceLap == NULL) // If there is no reference lap currently - { - m_pReferenceLap = pNewLap; // by default, make the first lap received the reference lap - } - if(pLap->GetComment().size() <= 0) - { - pLap->SetComment(m_szCommentText); - } - m_mapLaps[pLap->GetLapId()] = pNewLap; - } - } - } - } - - void ApplyDriverNameToSelectedLaps(ILapReceiver* pLapDB) - { - set setSelectedData = m_sfLapList.GetSelectedItemsData(); - for(set::iterator i = setSelectedData.begin(); i != setSelectedData.end(); i++) - { - // the ints of this set are actually pointers to CExtendedLap objects - CExtendedLap* pLap = (CExtendedLap*)(*i); - pLap->GetLap()->SetComment(m_szCommentText); - } - } - - virtual void SetLapHighlightTime(const CExtendedLap* pLap, int iTimeMs) override - { - m_mapLapHighlightTimes[pLap] = iTimeMs; - } - virtual int GetLapHighlightTime(const CExtendedLap* pLap) const override - { - DASSERT(m_mapLapHighlightTimes.find(pLap) != m_mapLapHighlightTimes.end()); // this should have always ended up set from the "master" highlighter. This function is only called by "slave" highlight-users - return m_mapLapHighlightTimes.find(pLap)->second; - } - virtual bool IsHighlightSource(int iSupplierId) const override - { - switch(iSupplierId) - { - case SUPPLIERID_MAINDISPLAY: - return true; // main display is always the driver of highlight data - case SUPPLIERID_SUBDISPLAY: - return false; - case SUPPLIERID_SECTORDISPLAY: - return true; // Allow the Set Split Sectors to be highlight source - case SUPPLIERID_TRACTIONCIRCLEDISPLAY: - return false; // main display is always the driver of highlight data - default: - DASSERT(FALSE); - return false; - } - } - - virtual vector GetAllLaps() const override - { - set setSelectedLaps = m_sfLapList.GetSelectedItemsData(); - vector lstLaps; - for(map::const_iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) - { - CExtendedLap* pLap = i->second; - lstLaps.push_back(pLap); - } - - return lstLaps; - } - virtual vector GetLapsToShow() const override - { - set setSelectedLaps = m_sfLapList.GetSelectedItemsData(); - vector lstLaps; - map mapFastestDriver; - CExtendedLap* pFastest = NULL; - CExtendedLap* pReference = NULL; // Added to show Reference Lap - KDJ - for(set::iterator i = setSelectedLaps.begin(); i != setSelectedLaps.end(); i++) - { - CExtendedLap* pLap = (CExtendedLap*)*i; - - lstLaps.push_back(pLap); - } - - for(map::const_iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) - { - CExtendedLap* pLap = i->second; - if(m_fShowDriverBests && (mapFastestDriver.count(pLap->GetLap()->GetComment()) == 0 || pLap->GetLap()->GetTime() < mapFastestDriver[pLap->GetLap()->GetComment()]->GetLap()->GetTime())) - { - mapFastestDriver[pLap->GetLap()->GetComment()] = pLap; - } - if(m_fShowBests) - { - if(pFastest == NULL || pLap->GetLap()->GetTime() < pFastest->GetLap()->GetTime()) - { - pFastest = pLap; - } - } - } - - if(m_fShowBests && pFastest) - { - lstLaps.push_back(pFastest); - } - for(map::iterator i = mapFastestDriver.begin(); i != mapFastestDriver.end(); i++) - { - lstLaps.push_back(i->second); - } - - // Set up for showing Reference lap similar to how we show Fastest Lap. - if(m_fShowReferenceLap && m_pReferenceLap != NULL) - { - lstLaps.push_back(m_pReferenceLap); - } - - - return lstLaps; - } - virtual FLOATRECT GetAllLapsBounds() const override - { - FLOATRECT rc; - rc.left = 1e30; - rc.top = -1e30; - rc.bottom = 1e30; - rc.right = -1e30; - - // changed this so it returns the bounds of the reference lap. This way, data-viewing isn't ruined by errant points - // it used to be based on all the laps, but if you had just one messed-up lap it would make viewing pointless - if(m_pReferenceLap != NULL) - { - const vector& lstPoints = m_pReferenceLap->GetPoints(); - for(int x = 0; x< lstPoints.size(); x++) - { - const TimePoint2D& p = lstPoints[x]; - rc.left = min(rc.left,p.flX); - rc.top = max(rc.top,p.flY); - rc.bottom = min(rc.bottom,p.flY); - rc.right = max(rc.right,p.flX); - } - - rc.left += m_flShiftX; - rc.top += m_flShiftY; - rc.right += m_flShiftX; - rc.bottom += m_flShiftY; - } - return rc; - } - virtual LAPDISPLAYSTYLE GetLapDisplayStyle(int iSupplierId) const override - { - switch(iSupplierId) - { - case SUPPLIERID_MAINDISPLAY: - { - vector lstLaps = GetLapsToShow(); - if(lstLaps.size() <= 0) return LAPDISPLAYSTYLE_NOLAPS; - return m_eLapDisplayStyle; - } - case SUPPLIERID_SUBDISPLAY: - switch(m_eLapDisplayStyle) - { - case LAPDISPLAYSTYLE_MAP: return LAPDISPLAYSTYLE_PLOT; - default: return LAPDISPLAYSTYLE_MAP; - } - case SUPPLIERID_TRACTIONCIRCLEDISPLAY: - { - return LAPDISPLAYSTYLE_TRACTIONCIRCLE; - } - case SUPPLIERID_SECTORDISPLAY: - { - return LAPDISPLAYSTYLE_MAP; - } - default: - DASSERT(FALSE); - break; - } - return m_eLapDisplayStyle; - } - virtual float GetDataHardcodedMin(DATA_CHANNEL eChannel) const override - { - if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || - eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END) - { - return m_sfLapOpts.fIOIOHardcoded ? 0 : 1e30; - } - return 1e30; - } - virtual float GetDataHardcodedMax(DATA_CHANNEL eChannel) const override - { - if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || - eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END) - { - return m_sfLapOpts.fIOIOHardcoded ? 5 : -1e30; - } - return -1e30; - } - - virtual float GetGuideStartX(DATA_CHANNEL eChannel, float flMin, float flMax) override - { - CASSERT(DATA_CHANNEL_COUNT == 0x401); - - switch(eChannel) - { - case DATA_CHANNEL_X: return 1e30; - case DATA_CHANNEL_Y: return 1e30; // we don't want guides for either latitude or longitude - case DATA_CHANNEL_VELOCITY: - { - int iMin = (int)(flMin); - return (float)(iMin); - } - case DATA_CHANNEL_DISTANCE: - { - int iMin = (int)(flMin); - return (float)(iMin); - } - case DATA_CHANNEL_TIME: - case DATA_CHANNEL_ELAPSEDTIME: - case DATA_CHANNEL_TIMESLIP: - case DATA_CHANNEL_LAPTIME_SUMMARY: - { - int iMin = (int)(flMin/1000.0f); - return (float)(iMin)*1000.0f; - } - case DATA_CHANNEL_X_ACCEL: - case DATA_CHANNEL_Y_ACCEL: - case DATA_CHANNEL_Z_ACCEL: - { - int iMin = (int)(flMin); - return (float)(iMin); - } - case DATA_CHANNEL_TEMP: return 0; - case (DATA_CHANNEL_PID_START+0x5): return -40; - case (DATA_CHANNEL_PID_START+0xc): return 0; - case (DATA_CHANNEL_PID_START+0xA): return 0; - case (DATA_CHANNEL_PID_START+0x5c): return -40; - default: - if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || - eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END) - { - return m_sfLapOpts.fIOIOHardcoded ? 0 : 1e30; - } - return 1e30; - } - } - - virtual float GetGuideStart(DATA_CHANNEL eChannel, float flMin, float flMax) override - { - CASSERT(DATA_CHANNEL_COUNT == 0x401); - - switch(eChannel) - { - case DATA_CHANNEL_X: return 1e30; - case DATA_CHANNEL_Y: return 1e30; // we don't want guides for either latitude or longitude - case DATA_CHANNEL_VELOCITY: return 0; - case DATA_CHANNEL_DISTANCE: return 1e30; - case DATA_CHANNEL_TIME: - case DATA_CHANNEL_ELAPSEDTIME: - case DATA_CHANNEL_TIMESLIP: - { - int iMin = (int)(flMin/1000.0f); - return (float)(iMin)*1000.0f; - } - case DATA_CHANNEL_LAPTIME_SUMMARY: - { - int iMin = (int)(flMin); - return (float)(iMin); - } - case DATA_CHANNEL_X_ACCEL: - case DATA_CHANNEL_Y_ACCEL: - case DATA_CHANNEL_Z_ACCEL: - { - int iMin = (int)(flMin); - return (float)(iMin); - } - case DATA_CHANNEL_TEMP: return 0; - - default: - if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || - eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END) - { - return m_sfLapOpts.fIOIOHardcoded ? 0 : 1e30; - } - else if(eChannel >= DATA_CHANNEL_PID_START && eChannel < DATA_CHANNEL_PID_END) - { - int iMin = (int)(flMin); - return (float)(iMin); - } - return 1e30; - } - } - - virtual float GetGuideStepX(DATA_CHANNEL eChannel, float flMin, float flMax) override - { - // Function sets up the spacing for the vertical guidelines on the data plots - CASSERT(DATA_CHANNEL_COUNT == 0x401); - const float flSpread = flMax - flMin; - switch(eChannel) - { - case DATA_CHANNEL_X: return 1e30; - case DATA_CHANNEL_Y: return 1e30; // we don't want guides for either latitude or longitude - case DATA_CHANNEL_VELOCITY: // We need to fix the X-channel call before putting these back into the code. - { - switch(m_sfLapOpts.eUnitPreference) - { - case UNIT_PREFERENCE_KMH: return KMH_TO_MS(25.0); - case UNIT_PREFERENCE_MPH: return MPH_TO_MS(20.0); // Adjusted by KDJ - case UNIT_PREFERENCE_MS: return 5; - } - return 10.0; - } - case DATA_CHANNEL_DISTANCE: - { - if(flSpread < 0.001) return 0.0001f; - if(flSpread < 0.005) return 0.0005f; - if(flSpread < 0.010) return 0.0010f; - if(flSpread < 0.050) return 0.0050f; - if(flSpread < 1.000) return 0.1000f; - if(flSpread < 10.00) return 1.0000f; - if(flSpread < 1000) return 50.0f; - if(flSpread < 5000) return 100.0f; - if(flSpread < 10000) return 500.0f; - if(flSpread < 50000) return 2500.0f; - if(flSpread < 110000) return 5000.0f; - if(flSpread < 1100000) return 10000.0f; - if(flSpread < 10000000) return 100000.0f; - return 10000000; - } - - case DATA_CHANNEL_TIME: - case DATA_CHANNEL_ELAPSEDTIME: - { - if(flSpread < 1000) return 50.0f; - if(flSpread < 5000) return 100.0f; - if(flSpread < 10000) return 500.0f; - if(flSpread < 50000) return 2500.0f; - if(flSpread < 110000) return 5000.0f; - if(flSpread < 1100000) return 10000.0f; - if(flSpread < 10000000) return 100000.0f; - if(flSpread < 100000000) return 1000000.0f; - return 10000000.0f; - } - case DATA_CHANNEL_LAPTIME_SUMMARY: - { - if(flSpread < 1) return 0.50f; - if(flSpread < 5) return 1.0f; - if(flSpread < 10) return 5.0f; - if(flSpread < 50) return 25.0f; - if(flSpread < 110) return 50.0f; - if(flSpread < 1100) return 100.0f; - if(flSpread < 10000) return 1000.0f; - if(flSpread < 50000) return 2500.0f; - if(flSpread < 110000) return 5000.0f; - if(flSpread < 1100000) return 10000.0f; - if(flSpread < 10000000) return 100000.0f; - if(flSpread < 100000000) return 1000000.0f; - return 10000000.0f; - } - default: - return 1e30; - } - } - - virtual float GetGuideStep(DATA_CHANNEL eChannel, float flMin, float flMax) override - { - CASSERT(DATA_CHANNEL_COUNT == 0x401); - const float flSpread = flMax - flMin; - switch(eChannel) - { - case DATA_CHANNEL_X: return 1e30; - case DATA_CHANNEL_Y: return 1e30; // we don't want guides for either latitude or longitude - case DATA_CHANNEL_VELOCITY: - { - switch(m_sfLapOpts.eUnitPreference) - { - case UNIT_PREFERENCE_KMH: return KMH_TO_MS(25.0); - case UNIT_PREFERENCE_MPH: return MPH_TO_MS(20.0); // Adjusted by KDJ - case UNIT_PREFERENCE_MS: return 5; - } - return 10.0; - } - case DATA_CHANNEL_DISTANCE: - { - if(flSpread < 0.001) return 0.0001f; - if(flSpread < 0.005) return 0.0005f; - if(flSpread < 0.010) return 0.0010f; - if(flSpread < 0.050) return 0.0050f; - if(flSpread < 1.000) return 0.1000f; - if(flSpread < 10.00) return 1.0000f; - if(flSpread < 1000) return 100.0f; - if(flSpread < 5000) return 500.0f; - if(flSpread < 10000) return 1000.0f; - if(flSpread < 50000) return 5000.0f; - if(flSpread < 110000) return 10000.0f; - if(flSpread < 1100000) return 100000.0f; - if(flSpread < 10000000) return 1000000.0f; - return 10000000; - } - - case DATA_CHANNEL_TIME: return 1e30; // No guidelines for Y-axis - case DATA_CHANNEL_TIMESLIP: - case DATA_CHANNEL_ELAPSEDTIME: - { - if(flSpread < 10) return 1.0f; - if(flSpread < 100) return 10.0f; - if(flSpread < 1000) return 100.0f; - if(flSpread < 5000) return 500.0f; - if(flSpread < 10000) return 1000.0f; - if(flSpread < 50000) return 5000.0f; - if(flSpread < 110000) return 10000.0f; - if(flSpread < 1100000) return 100000.0f; - if(flSpread < 10000000) return 1000000.0f; - return 10000000.0f; - } - case DATA_CHANNEL_LAPTIME_SUMMARY: - { - if(flSpread < 5) return 0.5f; - if(flSpread < 10) return 1.0f; - if(flSpread < 50) return 5.0f; - if(flSpread < 100) return 10.0f; - if(flSpread < 1100) return 100.0f; - if(flSpread < 10000) return 1000.0f; - if(flSpread < 50000) return 5000.0f; - if(flSpread < 110000) return 10000.0f; - if(flSpread < 1100000) return 100000.0f; - if(flSpread < 10000000) return 1000000.0f; - return 10000000.0f; - } - case DATA_CHANNEL_X_ACCEL: return 0.5f; - case DATA_CHANNEL_Y_ACCEL: return 0.5f; - case DATA_CHANNEL_Z_ACCEL: return 0.5f; - case DATA_CHANNEL_TEMP: return 10.0f; - - default: - if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || - eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END) - { - if(flSpread < 1) return m_sfLapOpts.fIOIOHardcoded ? 0.1f : 1e30; - if(flSpread < 10) return m_sfLapOpts.fIOIOHardcoded ? 1.0f : 1e30; - if(flSpread < 25) return m_sfLapOpts.fIOIOHardcoded ? 2.5f : 1e30; - if(flSpread < 50) return m_sfLapOpts.fIOIOHardcoded ? 5.0f : 1e30; - if(flSpread < 150) return m_sfLapOpts.fIOIOHardcoded ? 20.0f : 1e30; - if(flSpread < 500) return m_sfLapOpts.fIOIOHardcoded ? 50.0f : 1e30; - if(flSpread < 10000) return m_sfLapOpts.fIOIOHardcoded ? 1000.0f : 1e30; - if(flSpread < 100000) return m_sfLapOpts.fIOIOHardcoded ? 5000.0f : 1e30; - if(flSpread < 1000000) return m_sfLapOpts.fIOIOHardcoded ? 50000.0f : 1e30; - return m_sfLapOpts.fIOIOHardcoded ? 1.0f : 1e30; // Original code, and default for non-transformed IOIO data - } - else if(eChannel >= DATA_CHANNEL_PID_START && eChannel < DATA_CHANNEL_PID_END) - { - if(flSpread < 1) return 0.1f; - if(flSpread < 10) return 1.0f; - if(flSpread < 25) return 2.5f; - if(flSpread < 50) return 5.0f; - if(flSpread < 150) return 20.0f; - if(flSpread < 500) return 50.0f; - if(flSpread < 10000) return 1000.0f; - if(flSpread < 100000) return 5000.0f; - if(flSpread < 1000000) return 50000.0f; - return 1e30; - } - return 1e30; - } - } - virtual const LAPSUPPLIEROPTIONS& GetDisplayOptions() const override - { - return m_sfLapOpts; - } - virtual DATA_CHANNEL GetXChannel() const override - { - return m_eXChannel; - } - virtual const IDataChannel* GetChannel(int iLapId, DATA_CHANNEL eChannel) const override - { - return g_pLapDB->GetDataChannel(iLapId, eChannel); - } - virtual vector GetYChannels() const override - { - return m_lstYChannels; - } - virtual void GetResponse(const char* pbData, int cbData, char** ppbResponse, int* pcbResponse) - { - - } - void SetupMulticast() - { - IP_ADAPTER_INFO sfAdapter[255] = {0}; - ULONG cbAdapter = sizeof(sfAdapter); - ULONG ret = GetAdaptersInfo(sfAdapter, &cbAdapter); - int cConnected = 0; - if(ret == NO_ERROR) - { - IP_ADAPTER_INFO* pInfo = &sfAdapter[0]; - while(pInfo) - { - if(strcmp(pInfo->IpAddressList.IpAddress.String, "0.0.0.0") != 0) - { - // found an adapter. That means we need a multicast checker - MulticastListener* pListener = new MulticastListener(&m_sfResponder, pInfo->IpAddressList.IpAddress.String); - if(pListener->Start()) - { - m_lstMulticast.push_back(pListener); - } - else - { - delete pListener; - } - } - - pInfo = pInfo->Next; - } - } - } -public: - vector m_lstYChannels; - ArtListBox m_sfYAxis; - ArtListBox m_sfLapList; -private: - ArtListBox m_sfXAxis; - - CLapPainter m_sfLapPainter; - CLapPainter m_sfSubDisplay; - CLapPainter m_sfTractionDisplay; - - // lap display style data - map m_mapLapHighlightTimes; // stores the highlight times (in milliseconds since phone app start) for each lap. Set from ILapSupplier calls - - LAPDISPLAYSTYLE m_eLapDisplayStyle; - DATA_CHANNEL m_eXChannel; -// vector m_lstYChannels; - bool m_fShowTractionCircle; - bool m_fShowBests; - bool m_fShowDriverBests; - bool m_fShowReferenceLap; - - CExtendedLap* m_pReferenceLap; - map m_mapLaps; // maps from iLapId to a lap object - HWND m_hWnd; - - map m_baseWindowPos; - - TCHAR m_szCommentText[512]; - TCHAR m_szMessageStatus[512]; - - // what updates are needed. When we call UpdateUI, it will |= the requested flags onto this, and then do a PostMessage with a custom UPDATEUI message - // when the UPDATEUI message is received, it will do an UpdateUI_Internal call using all the flags that have been built up, and clear the ones it handled. - DWORD m_fdwUpdateNeeded; - - // panning/zooming - float m_flShiftX; - float m_flShiftY; - - // multicast responses for each network device detected - vector m_lstMulticast; - MCResponder m_sfResponder; - - int m_iRaceId[50]; - ILapSupplier* z_ILapSupplier; -}; - -DWORD ReceiveThreadProc(LPVOID param) -{ - ILapReceiver* pLaps = (ILapReceiver*)param; - while(true) - { - ReceiveLaps(63939, pLaps); - } - return 0; -} - -int str_ends_with(const TCHAR * str, const TCHAR * suffix) -{ - if( str == NULL || suffix == NULL ) - return 0; - - size_t str_len = wcslen(str); - size_t suffix_len = wcslen(suffix); - - if(suffix_len > str_len) - return 0; - - return 0 == wcsncmp( str + str_len - suffix_len, suffix, suffix_len ); -} - -void LoadPitsideSettings(PITSIDE_SETTINGS* pSettings) -{ - pSettings->Default(); - - TCHAR szModule[MAX_PATH]; - if(GetAppFolder(szModule,NUMCHARS(szModule))) - { - wcsncat(szModule,L"settings.txt", NUMCHARS(szModule)); - - ifstream in; - in.open(szModule); - if(!in.eof() && !in.fail()) - { - in>>pSettings->fRunHTTP; - in>>pSettings->iHTTPPort; - in>>pSettings->iVelocity; - in>>pSettings->iMapLines; - in>>pSettings->iColorScheme; - in.close(); - } - } - else - { - // trouble. just bail. - return; - } -} - -void InitPlotPrefs(LAPSUPPLIEROPTIONS &p_sfLapOpts) - { + + if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_VALUES)) + { + UpdateValues(); + UpdateSectors(); + } + if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_MAP)) + { + UpdateDisplays(); + } + if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_MENU)) + { + UpdateMenus(); + } + if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_ALLDATA)) + { + UpdateAllData(); + } + + if(IS_FLAG_SET(fdwUpdateFlags, UPDATE_DASHBOARD)) + { + set setSelectedChannels; + + for(set::const_iterator i = setSelectedData.begin(); i != setSelectedData.end(); i++) + { + CExtendedLap* pLap = (CExtendedLap*)(*i); + set setLapData = pLap->GetAvailableChannels(); + for(set::iterator i = setLapData.begin(); i != setLapData.end(); i++) + { + setSelectedChannels.insert(*i); + } + } + + CASSERT(LAPDISPLAYSTYLE_COUNT == 4); + switch(m_eLapDisplayStyle) + { + case LAPDISPLAYSTYLE_MAP: CheckRadioButton(m_hWnd, IDC_DISPLAYTYPE_LINE, IDC_DISPLAYTYPE_LAST, IDC_DISPLAYTYPE_LINE); break; + case LAPDISPLAYSTYLE_PLOT: CheckRadioButton(m_hWnd, IDC_DISPLAYTYPE_LINE, IDC_DISPLAYTYPE_LAST, IDC_DISPLAYTYPE_PLOT); break; + case LAPDISPLAYSTYLE_RECEPTION: CheckRadioButton(m_hWnd, IDC_DISPLAYTYPE_LINE, IDC_DISPLAYTYPE_LAST, IDC_DISPLAYTYPE_RECEPTION); break; + default: DASSERT(FALSE); break; + } + + set setXSelected,setYSelected; + setXSelected.insert(m_eXChannel); + m_sfXAxis.SetSelectedData(setXSelected); + + for(int x = 0; x < m_lstYChannels.size(); x++) + { + setYSelected.insert(m_lstYChannels[x]); + } + m_sfYAxis.SetSelectedData(setYSelected); + + HWND hDriverButton = GetDlgItem(m_hWnd, IDC_SETDRIVER); + Button_Enable(hDriverButton, setSelectedData.size() > 0); + HWND hReferenceButton = GetDlgItem(m_hWnd, IDC_SETREFERENCE); + Button_Enable(hReferenceButton, setSelectedData.size() == 1); + + HWND hWndReference = GetDlgItem(m_hWnd, IDC_CURRENTREFERENCE); + if(m_pReferenceLap) + { + TCHAR szRefString[512] = L""; + TCHAR szLapString[512] = L""; + m_pReferenceLap->GetString(szLapString, NUMCHARS(szLapString)); + swprintf(szRefString, NUMCHARS(szRefString), L"Reference Lap: %s", szLapString); + SendMessage(hWndReference, WM_SETTEXT, 0, (LPARAM)szRefString); + } + else + { + SendMessage(hWndReference, WM_SETTEXT, 0, (LPARAM)L"No Reference Lap"); + } + HWND hWndMessageStatus = GetDlgItem(m_hWnd, IDC_MESSAGESTATUS); + SendMessage(hWndMessageStatus, WM_SETTEXT, 0, (LPARAM)m_szMessageStatus); + + InitAxes(setSelectedChannels); + } + } +private: + void ClearUILaps() + { + m_mapLapHighlightTimes.clear(); + m_pReferenceLap = NULL; + m_mapLaps.clear(); + m_sfLapList.Clear(); + } + bool ShowHelp(HWND hWnd) + { + TCHAR lpOpen[MAX_PATH] = L"open"; + + TCHAR lpFile[MAX_PATH] = L"PitsideHelp.pdf"; + TCHAR lpDir[MAX_PATH]; + if(GetAppFolder(lpDir,NUMCHARS(lpDir))) + { + // Set up the Filename string for the Help PDF file. + wcsncat(lpDir,L"", NUMCHARS(lpDir)-1); + } + else + { + // trouble. just bail. + return false; + } + int nShowCmd = SW_RESTORE; // Restore the Help document, if it is minimized or whatever. + + // Shell to the Help PDF file + HINSTANCE Check = ShellExecuteW(hWnd, lpOpen, lpFile, NULL, lpDir, nShowCmd); + if ((int)Check <= 32) + MessageBox(NULL, L"The Help file requires Acrobat Reader\n\nPlease install Reader and try again", L"Acrobat Reader Not Found", MB_OK); + return true; + } + bool ShowWFLHelp(HWND hWnd) + { + TCHAR lpOpen[MAX_PATH] = L"open"; + + TCHAR lpFile[MAX_PATH] = L"SpeedFreqHelp.pdf"; + TCHAR lpDir[MAX_PATH]; + if(GetAppFolder(lpDir,NUMCHARS(lpDir))) + { + // Set up the Filename string for the Help PDF file. + wcsncat(lpDir,L"", NUMCHARS(lpDir)-1); + } + else + { + // trouble. just bail. + return false; + } + int nShowCmd = SW_RESTORE; // Restore the Help document, if it is minimized or whatever. + + // Shell to the Help PDF file + HINSTANCE Check = ShellExecuteW(hWnd, lpOpen, lpFile, NULL, lpDir, nShowCmd); + if ((int)Check <= 32) + MessageBox(NULL, L"The Help file requires Acrobat Reader\n\nPlease install Reader and try again", L"Acrobat Reader Not Found", MB_OK); + return true; + } + void ShowNetInfo() + { + while(true) + { + TCHAR szBuf[1000]; + szBuf[0] = '\0'; + _snwprintf(szBuf, NUMCHARS(szBuf), L"PC IP Address[es] are displayed below. You will need one of these to put in the phone app.\n\n"); + + IP_ADAPTER_INFO sfAdapter[255] = {0}; + ULONG cbAdapter = sizeof(sfAdapter); + ULONG ret = GetAdaptersInfo(sfAdapter, &cbAdapter); + int cConnected = 0; + if(ret == NO_ERROR) + { + IP_ADAPTER_INFO* pInfo = &sfAdapter[0]; + while(pInfo) + { + TCHAR szLine[255]; + if(strcmp(pInfo->IpAddressList.IpAddress.String, "0.0.0.0") != 0) + { + _snwprintf(szLine, NUMCHARS(szLine), L"%S - %S\n", pInfo->Description, pInfo->IpAddressList.IpAddress.String); + wcsncat(szBuf,szLine, NUMCHARS(szBuf)); + cConnected++; + } + + pInfo = pInfo->Next; + } + + if(cConnected > 0) + { + MessageBox(NULL, szBuf, L"Ip address info", MB_OK); + return; + } + else + { + int iResult = MessageBox(NULL, L"WifiLapper Pitside cannot find any network devices connected. Please connect to a network and try again.", L"Could not find IP addresses", MB_ABORTRETRYIGNORE | MB_ICONWARNING); + if(iResult == IDABORT) + { + exit(0); + } + else if(iResult == IDRETRY) + { + // just let the loop roll + } + else if(iResult == IDIGNORE) + { + // ok, they just want to get to the app. + return; + } + } + } + } // loop for retrying + } + void InitAxes(set setAvailable) + { + static set setLast; + if(AreSetsEqual(setLast,setAvailable)) return; // nothing to do + + m_sfXAxis.Clear(); + m_sfYAxis.Clear(); + TCHAR szDataChannelName[MAX_PATH]; + for(set::const_iterator i = setAvailable.begin(); i != setAvailable.end(); i++) + { + GetDataChannelName(*i, szDataChannelName, NUMCHARS(szDataChannelName)); + m_sfXAxis.AddString(szDataChannelName,*i); + m_sfYAxis.AddString(szDataChannelName,*i); + } + setLast = setAvailable; + } + void InitBaseWindowPos() + { +#define GET_WINDOWPOS(idc) \ + { \ + WINDOWPLACEMENT wp; \ + wp.length = sizeof(wp); \ + HWND hWnd = GetDlgItem(m_hWnd,idc); \ + GetWindowPlacement(hWnd, &wp); \ + m_baseWindowPos[idc] = wp.rcNormalPosition; \ + } + WINDOWPLACEMENT wp; + wp.length = sizeof(wp); + HWND hWnd = m_hWnd; + GetWindowPlacement(hWnd, &wp); + m_baseWindowPos[IDD_DLGFIRST] = wp.rcNormalPosition; + + GET_WINDOWPOS(IDC_DISPLAY); +// GET_WINDOWPOS(IDD_DLGSUBDISPLAY); + GET_WINDOWPOS(IDC_SUBDISPLAY); + GET_WINDOWPOS(IDC_LAPS); + GET_WINDOWPOS(IDC_TRACTIONCIRCLEMAP); + GET_WINDOWPOS(IDC_ALLDATADISPLAY); + + } + void HandleCtlResize(SIZE sNewSize, int idc, bool fResizeX, bool fResizeY) + { + HWND hwndMainView = GetDlgItem(m_hWnd, idc); + RECT rcBasePos = m_baseWindowPos[idc]; + SIZE sNewCtlSize = {fResizeX ? (sNewSize.cx - rcBasePos.left) : RECT_WIDTH(&rcBasePos), fResizeY ? (sNewSize.cy - rcBasePos.top) : RECT_HEIGHT(&rcBasePos)}; + MoveWindow(hwndMainView, rcBasePos.left, rcBasePos.top, sNewCtlSize.cx, sNewCtlSize.cy, TRUE); + } + void HandleResize(SIZE sNewSize) + { + HandleCtlResize(sNewSize, IDC_DISPLAY, true, true); // main display window +// HandleCtlResize(sNewSize, IDD_DLGSUBDISPLAY, true, true); // sub display window + HandleCtlResize(sNewSize, IDC_SUBDISPLAY, true, false); // sub display control + HandleCtlResize(sNewSize, IDC_LAPS, false, true); // lap list + HandleCtlResize(sNewSize, IDC_TRACTIONCIRCLEMAP, false, false); // Traction circle window + } + + // Function updates the data points in the window showing all of the data for the selected laps, activated by the middle mouse button + void UpdateAllData() + { + // hWnd_AllData is the handle for the window we want. Let's make sure that it is displayed + // Let's define some colors for the List Views to use + COLORREF d_BlackColor = RGB(0, 0, 0); // Black + COLORREF d_WhiteColor = RGB(255, 255, 255); // White + COLORREF d_RedColor = RGB(230, 20, 20); // Red + COLORREF d_GreenColor = RGB(20, 230, 20); // Green + COLORREF d_LGreyColor = RGB(200, 200, 200); // Light Grey + HDC AD_Rect = GetDC(AD_hWnd); // HDC for the display control + + if (GetDlgItem(hWnd_AllData, IDC_ALLDATADISPLAY)) // Only execute data display functions if window is showing + { + // First let's get all of the information about the data points for this lap/location + ListView_DeleteAllItems(AD_hWnd); // Clear the list before displaying the update + vector lstLaps = GetLapsToShow(); // Load the CExtendedLap data for the lap list + if(lstLaps.size() > 0) + { + const int cLaps = 10; // The maximum number of Laps to display Data channels for, limited by the window form + int iLap = 0; // Tracking variable for which Lap we are on in the loop + int iChannel = 0; // Tracking variable for which Y-Channel we are on within each lap + int iTotChannel = 0; // The number of Y Data channels in the Listview + // Loop through each lap and pick up all of their values for each data channel + for(vector::iterator a = lstLaps.begin(); a != lstLaps.end(); a++) + { + CExtendedLap* pLap = (CExtendedLap*)*a; + // For each lap let's get all of the available data channels for display + int TotalYChannels = 0; // Total numbber of Data Channels availalbe for this lap + int iLapId = pLap->GetLap()->GetLapId(); + set channels = pLap->GetAvailableChannels(); // Get all of the data channels for this lap + if ( !iTotChannel ) iTotChannel = channels.size(); // Only update the first time through the LV creation loop + for(set::const_iterator i = channels.begin(); i != channels.end(); i++) // Loop through them, insert them into our "all data channels" set + { + TCHAR m_szYString[512] = {NULL}; + TCHAR szLabel[50][MAX_PATH] = {NULL}; // Assumes that we will have no more than 50 Y-Data channels + TotalYChannels = channels.size(); // The number of Data Channels available for this lap + DATA_CHANNEL eChannel = *i; + if( !eChannel ) continue; + float flVal; + // Let's get the value for this data channel at this highlight point + const IDataChannel* pChannel = pLap->GetChannel(eChannel); + if (pChannel) // Check if pointer is valid + { + flVal = pChannel->GetValue(m_mapLapHighlightTimes[pLap]); // The value that we are looking for + ////////////////////////////////////////// + // Adding transformation functions here for Y + if (m_sfLapOpts.m_PlotPrefs[iChannel].iTransformYesNo == true) + { + if (m_sfLapOpts.m_PlotPrefs[iChannel].fTransBValue < 0) + { + flVal = m_sfLapOpts.m_PlotPrefs[iChannel].fTransAValue + flVal * m_sfLapOpts.m_PlotPrefs[iChannel].fTransBValue + flVal * flVal * m_sfLapOpts.m_PlotPrefs[iChannel].fTransCValue; + } + else + { + flVal = m_sfLapOpts.m_PlotPrefs[iChannel].fTransAValue + flVal * m_sfLapOpts.m_PlotPrefs[iChannel].fTransBValue + flVal * flVal * m_sfLapOpts.m_PlotPrefs[iChannel].fTransCValue; + } + } + ////////////////////////////////////////// + // Now assign these values to the Data Value variable for display + TCHAR szChannelName[MAX_PATH]; + GetDataChannelName(eChannel,szChannelName,NUMCHARS(szChannelName)); + + char szVal[MAX_PATH]; + GetChannelValue(eChannel,m_sfLapOpts.eUnitPreference,flVal,szVal,NUMCHARS(szVal)); // Value for data channels + + TCHAR szDate[100]; + pLap->GetString(szDate, 9); // Truncated timestamp of this lap, to used to name it + + // Let's load the Listview with this result + TCHAR lstVal[MAX_PATH] ; + swprintf(lstVal,NUMCHARS(lstVal), L"%S", szVal); + wchar_t result[MAX_PATH] ; + bool b_LV_ChannelFound = false; // ListView boolean for Data Channel searches + // First set up the Main listview item (Data Channel Name) for the first lap + int i_TextResult = 0; // Data channel matching integer + if (iLap == 0 && iChannel == 0 ) + { + p_ADlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_ADlvi.iItem = 0; // Which Data Channel subscript + p_ADlvi.iSubItem = 0; // Which Lap subscript + p_ADlvi.lParam = 0; + swprintf(result,NUMCHARS(result), L"Time"); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + // ListView_InsertItem(AD_hWnd, &p_ADlvi); // For the first item line let's use the Lap Start Time for Identification + SendMessage(AD_hWnd, LVM_INSERTITEM, 0, (LPARAM)&p_ADlvi); + + p_ADlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_ADlvi.iItem = iChannel + 1; // Which Data Channel subscript + p_ADlvi.iSubItem = 0; // Which Lap subscript + p_ADlvi.lParam = 0; + swprintf(result,NUMCHARS(result), szChannelName); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + // ListView_InsertItem(AD_hWnd, &p_ADlvi); // Put in the Data Channel name next + SendMessage(AD_hWnd, LVM_INSERTITEM, 0, (LPARAM)&p_ADlvi); + b_LV_ChannelFound = true; + } + else if (iLap == 0 && !iChannel == 0 ) + { + p_ADlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_ADlvi.iItem = iChannel + 1; // Which Data Channel subscript + p_ADlvi.iSubItem = 0; // Which Lap subscript + p_ADlvi.lParam = 0; + swprintf(result,NUMCHARS(result), szChannelName); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + // ListView_InsertItem(AD_hWnd, &p_ADlvi); // Put in the Data Channel name next + SendMessage(AD_hWnd, LVM_INSERTITEM, 0, (LPARAM)&p_ADlvi); + b_LV_ChannelFound = true; + } + else // Let's match up the Data Channel Name with those in the first lap for displaying in-line + { + // First let's get the channel name for this data channel + wchar_t result2[MAX_PATH]; + p_ADlvi.iItem = iChannel + 1; // The first lap's data channel name + p_ADlvi.iSubItem = 0; // The first lap's subscript + p_ADlvi.lParam = 0; + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.cchTextMax = MAX_PATH; + ListView_GetItem(AD_hWnd, &p_ADlvi); + + swprintf(result2,NUMCHARS(szChannelName), szChannelName); // szChannelName is the current Data Channel name we want to add the value to the LV + i_TextResult = wcscmp(p_ADlvi.pszText, result2); // Compare the wide strings to see if they match + if ( i_TextResult ) // 0 if they match, <>0 if they are different + { + // Items don't match. Let's see if the data channel exists in the array + for (int chan = 0; chan < iTotChannel; chan++) + { + // First let's get the channel name for this data channel + p_ADlvi.iItem = chan + 1; // The first lap's data channel name + p_ADlvi.iSubItem = 0; // The first lap's subscript + p_ADlvi.lParam = 0; + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.cchTextMax = MAX_PATH; + + if (ListView_GetItem(AD_hWnd, &p_ADlvi) ) // Returns TRUE if it gets an item + { + i_TextResult = wcscmp((LPWSTR)p_ADlvi.pszText, result2); // Compare the wide strings to see if they match + if ( !i_TextResult ) // 0 if they match, <>0 if they are different. Break loop if we found a match + { + iChannel = chan; // Set the LV Item subsript to the channel's number + b_LV_ChannelFound = true; // Set the "Channel Found" flag + break; + } + } + } // End of Data Channel searching loop + if ( b_LV_ChannelFound ) // Data Channel was found, now add the value to it + { + // Now populate the listview subitem with the datapoint value, if it's valid + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = iChannel + 1; // Which Data Channel subscript, +1 for "Lap" row + p_ADlvi.iSubItem = iLap + 1; // Which Lap subscript incremented to be positioned correctly + p_ADlvi.lParam = iLap + 1; + swprintf(result,NUMCHARS(result), lstVal); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + // ListView_SetItem(AD_hWnd, &p_ADlvi); + SendMessage(AD_hWnd, LVM_SETITEM, 0, (LPARAM)&p_ADlvi); + } + else // Data Channel doesn't exist in the list. Let's add it and the value. + { + p_ADlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_ADlvi.iItem = iTotChannel + 1; // Which Data Channel subscript + p_ADlvi.iSubItem = 0; // Which Lap subscript + p_ADlvi.lParam = 0; + swprintf(result2,NUMCHARS(szChannelName), szChannelName); + p_ADlvi.pszText = result2; + p_ADlvi.cchTextMax = wcslen(result2); + // ListView_InsertItem(AD_hWnd, &p_ADlvi); + SendMessage(AD_hWnd, LVM_INSERTITEM, 0, (LPARAM)&p_ADlvi); + + // Now populate the listview subitem with the datapoint value, if it's valid + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = iTotChannel + 1; // Which Data Channel subscript + p_ADlvi.iSubItem = iLap + 1; // Which Lap subscript incremented to be positioned correctly + p_ADlvi.lParam = iLap + 1; + swprintf(result,NUMCHARS(result), lstVal); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + // ListView_SetItem(AD_hWnd, &p_ADlvi); + SendMessage(AD_hWnd, LVM_SETITEM, 0, (LPARAM)&p_ADlvi); + + iTotChannel = iTotChannel + 1; // Increment the total number of data channels in the LV + } // End of data channel add test + + b_LV_ChannelFound = false; // Set the channel search flag to not found + } // End of Data Channel not matched test + else + { + b_LV_ChannelFound = true; // The channels match + } + } // End of Sub Item addition test + if (b_LV_ChannelFound ) + { + // Now populate the listview subitem with the datapoint value, if it's valid + if (iChannel == 0) // Put in Lap Name if it's the first row + { + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = 0; // Which Data Channel subscript + p_ADlvi.iSubItem = iLap + 1; // Which Lap subscript incremented to be positioned correctly + p_ADlvi.lParam = iLap + 1; + swprintf(result,NUMCHARS(szDate), szDate); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + // ListView_SetItem(AD_hWnd, &p_ADlvi); + SendMessage(AD_hWnd, LVM_SETITEM, 0, (LPARAM)&p_ADlvi); + + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = iChannel + 1; // Which Data Channel subscript + p_ADlvi.iSubItem = iLap + 1; // Which Lap subscript incremented to be positioned correctly + p_ADlvi.lParam = iLap + 1; + swprintf(result,NUMCHARS(result), lstVal); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + // ListView_SetItem(AD_hWnd, &p_ADlvi); + SendMessage(AD_hWnd, LVM_SETITEM, 0, (LPARAM)&p_ADlvi); + } + else // Populate with the data channel value + { + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = iChannel + 1; // Which Data Channel subscript + p_ADlvi.iSubItem = iLap + 1; // Which Lap subscript incremented to be positioned correctly + p_ADlvi.lParam = iLap + 1; + swprintf(result,NUMCHARS(result), lstVal); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + // ListView_SetItem(AD_hWnd, &p_ADlvi); + SendMessage(AD_hWnd, LVM_SETITEM, 0, (LPARAM)&p_ADlvi); + } + } + } // End Data Channel checking loop + iChannel++; // Increment the Data Channel counter and try to pull the next Data Channel information + } // End Data Channel Loop + // Increment the lap counter and get info from the next lap if we are less than our max. laps + if (iLap < cLaps) + { + iLap++; + iChannel = 0; // Reset the Data Channel Listview array counter for the next lap + } + else + { + break; + } + } // End Lap Loop + } // End Test Loop + } // End of Dialog present conditional + return; + } + + float fAverage(DATA_CHANNEL eChannel, const IDataChannel* pChannel, float flVal) + { + // This function returns the average value for the data channel across all data points from this lap. + char szAvg[MAX_PATH]; + float sum = 0.0f; + int count; + vector channels = pChannel->GetData(); // get the values for all of the data points + for (count = 0; count < channels.size(); count++) + { + GetChannelValue(eChannel,m_sfLapOpts.eUnitPreference,channels[count].flValue,szAvg,NUMCHARS(szAvg)); + sum = sum + atof(szAvg); + } + if (count != 0) + { + return sum / count; + } + else + { + return sum; + } + } + +void UpdateSectors() + { + // Update the Sector Times display + // The idea here is to get the sector positions and iTime from sfLapOpts, then for each highlighted + // Lap run through the Ref Lap Time/Distance array and interpolate the iTime at the equivalent distance + // Coding is similar to TimeSlip + // Let's define some colors for the List Views to use + COLORREF d_BlackColor = RGB(0, 0, 0); // Black + COLORREF d_WhiteColor = RGB(255, 255, 255); // White + COLORREF d_RedColor = RGB(230, 20, 20); // Red + COLORREF d_GreenColor = RGB(20, 230, 20); // Green + COLORREF d_LGreyColor = RGB(200, 200, 200); // Light Grey + LVBKIMAGE plvbki={0}; // Set background image to black + + if ( m_pReferenceLap != NULL && m_sfLapOpts.fDrawSplitPoints ) // First, let's make sure that we have a Reference Lap, or let's not perform this + { + HC_ShowSplits = GetDlgItem(hWndShowSplits, IDC_SHOW_SECTORS); // Let's get the handle for the display control in this window + HDC HC_Rect = GetDC(hWndShowSplits); // HDC for the display control + ListView_DeleteAllItems(HC_ShowSplits); // Clear the list before displaying the update + const int cSectors = 9; // The maximum number of Sectors to display, gated by display area + const int MaxLaps = 8; // Maximum number of laps to display + struct i_BestSectors + { + int iItem; + int iSubItem; + } + i_BestSectors[cSectors + 1] = {NULL}; // Initialize the Best Sectors array + float i_TheoreticalBestLap[cSectors + 1]; // +1 For the final Split Point + for (int a = 0; a < cSectors + 1; a++) + { + i_TheoreticalBestLap[a] = 999999.0f; // Initialize the Theorectical Best Lap + } + int w = 0; // Lap tracker for Sector display + int s = 0; // Sector tracker for Listview + + set setSelected = m_sfLapList.GetSelectedItemsData3(); // Get the list of highlighted lap time ID's + vector lstLaps = GetLapsToShow(); // Load the CExtendedLap data for the lap list + + // Get the points from the Ref Lap for computation + const vector& lstRefPoints = m_pReferenceLap->GetPoints(); // For iTime + const IDataChannel* pReferenceDistance = m_pReferenceLap->GetChannel(DATA_CHANNEL_DISTANCE); + + // Strings for building the Sector Times output for each lap + TCHAR szLapString[50][512] = {NULL}; + TCHAR szString[50][512] = {NULL}; + TCHAR szSectorTime[MAX_PATH] = {NULL}; // String containing the formatted sector time + float dSectorTime = 0; // Initialize the Sector Times variable + BOOL b_LineColor = false; // Flag for making alternating rows different colors + + SendMessage(HC_ShowSplits,LVM_SETBKIMAGE,0,(LPARAM)(LPLVBKIMAGE)&plvbki); // Set background color of LV + SendMessage(HC_ShowSplits,LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_FULLROWSELECT); // Set style + + // Lap Loop + // Now loop through the lap list, compute the sector times and store them in SplitPoints[] + for(vector::iterator i = lstLaps.begin(); i != lstLaps.end(); i++) + { + CExtendedLap* pLap = *i; // Get the data points for this lap, and compare the sector times to the Reference Lap (m_pReferenceLap) + const vector& lstLapPoints = pLap->GetPoints(); // Get the points from the Selected Lap for computation + pLap->GetString(szLapString[w], NUMCHARS(szLapString)); // Timestamp of this lap, to used to name it + + // Let's load the Listview row titles with this result + wchar_t result[MAX_PATH] ; + p_ADlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_ADlvi.iItem = w; // Which Lap subscript + p_ADlvi.iSubItem = 0; // Which Sector subscript (0 = Lap Name string) + p_ADlvi.lParam = 0; + swprintf(result,NUMCHARS(result), szLapString[w]); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + ListView_InsertItem(HC_ShowSplits, &p_ADlvi); // Using the lap time stamp/string for its name + + const IDataChannel* pDistance = pLap->GetChannel(DATA_CHANNEL_DISTANCE); + int iLapStartTime = lstLapPoints[0].iTime; + + // Sector Loop + // Now loop through the split points and determine lap times for each sector + for(s = 1; s <= cSectors; s++) + { + const int SectorStartTime = m_sfLapOpts.m_SplitPoints[s].m_sfSectorTime; // Get the Split Point iTime and it's distance value + const double dSectorDistance = pReferenceDistance->GetValue((int)SectorStartTime); // First iTime for the lap array + bool b_SectorFlag = false; + double dLastLapDist = 0; + + // Interpolation Loop + // Now go through the lap array and find the 2 points that span the dSectorDistance distance + for (int x = 1; x < lstLapPoints.size(); x++) + { + const int iElapsedTime = lstLapPoints[x].iTime - iLapStartTime; + const double dDistance = pDistance->GetValue(lstLapPoints[x].iTime); + dLastLapDist = pDistance->GetValue(lstLapPoints[x-1].iTime); + + TimePoint2D pLapPoint = lstLapPoints[x]; + // this lap's time at {dDistance} was {iElapsedTime}. + // we now need to estimate what the lap time at {dDistance} was, and then we can get our sector time + const int cLapSize = lstLapPoints.size(); + if(dDistance >= dSectorDistance && dLastLapDist <= dSectorDistance) + { + // we have found two points straddling the distance we're curious about, dSectorDistance + const double dOffset = dSectorDistance - dLastLapDist; // how far into the {dLastRefDist,dRefDist} x axis we are + const double dWidth = dDistance - dLastLapDist; // how far apart {dLastRefDist,dRefDist} are + double dFraction = 0; + if(dWidth != 0) + { + dFraction = dOffset / dWidth; // the fraction that dDistance is between dLastLapDist and dDistance + if(dFraction >= 0.0 && dFraction <= 1.0) + { + const int iLastTime = lstLapPoints[x-1].iTime; + const int iThisTime = lstLapPoints[x].iTime; + const double dEstimatedElapsedTime = dFraction * (iThisTime - iLastTime) + (double)iLastTime; + // this is the estimated time for the previous lap at this position + if(dEstimatedElapsedTime >= 0) + { + dSectorTime = dEstimatedElapsedTime - (double)iLapStartTime; + // Now that we have computed the Sector Time, let's put it in the Sector times string + if ( dSectorTime > 1 ) // 1 used for roundoff error + { + swprintf(szSectorTime, NUMCHARS(szSectorTime), L"%4.2f", dSectorTime/1000); + } + else + { + swprintf(szSectorTime, NUMCHARS(szSectorTime), L"", NULL); + } + iLapStartTime = dEstimatedElapsedTime; + dLastLapDist = dSectorDistance; + break; + } + } + } + else + { + const int iLastTime = lstLapPoints[x-1].iTime; + dSectorTime = iLastTime - (double)iLapStartTime; + // Now that we have computed the Sector Time, let's put it in the Sector times string + if ( dSectorTime > 1 ) // 1 used for roundoff error + { + swprintf(szSectorTime, NUMCHARS(szSectorTime), L"%4.2f", dSectorTime/1000); + } + else + { + swprintf(szSectorTime, NUMCHARS(szSectorTime), L"", NULL); + } + iLapStartTime = iLastTime; + dLastLapDist = dSectorDistance; + break; + } + } + if (x == lstLapPoints.size()-1) + { + // We've reached the end of the loop. Dump the last point as the last sector time, if other conditions failed + const int iLastTime = lstLapPoints[lstLapPoints.size()-1].iTime; + dSectorTime = iLastTime - (double)iLapStartTime; + // Now that we have computed the Sector Time, let's put it in the Sector times string + if ( dSectorTime > 1 ) // 1 used for roundoff error + { + swprintf(szSectorTime, NUMCHARS(szSectorTime), L"%4.2f", dSectorTime/1000); + } + else + { + swprintf(szSectorTime, NUMCHARS(szSectorTime), L"", NULL); + } + iLapStartTime = iLastTime; + dLastLapDist = dSectorDistance; + break; + } + } // End Interpolation Loop + + // Insert the item into the Listview + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = w; // Which Lap subscript + p_ADlvi.iSubItem = s; // Which Sector subscript incremented to be positioned correctly + p_ADlvi.lParam = s; + swprintf(result,NUMCHARS(result), szSectorTime); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + ListView_SetItem(HC_ShowSplits, &p_ADlvi); + if (dSectorTime < i_TheoreticalBestLap[s] ) // Save sector information if this is the fastest + { + i_BestSectors[s].iItem = w; + i_BestSectors[s].iSubItem = s; + i_TheoreticalBestLap[s] = dSectorTime; + } + + } // End Sector Loop + w++; // Increment "w" counter and do the next lap + if (w >= MaxLaps) break; // Stop building these if we already have as many as we need. + } // Lap Loop end + + // Now let's load the Listview with the Best Theorectical Lap information + float f_TheoreticalBestLap = 0.0f; + for (int t = 1; t <= cSectors; t++) + { + f_TheoreticalBestLap = f_TheoreticalBestLap + i_TheoreticalBestLap[t]; + } + TCHAR szLap[MAX_PATH]; + wchar_t result[MAX_PATH] ; + p_ADlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_ADlvi.iItem = w; // Which Lap subscript + p_ADlvi.iSubItem = 0; // Which Sector subscript (0 = Lap Name string) + p_ADlvi.lParam = 0; + ::FormatTimeMinutesSecondsMs(f_TheoreticalBestLap/1000, szLap, NUMCHARS(szLap) ); + swprintf(result,NUMCHARS(result), L"Theoretical Best: %s", szLap ); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + ListView_InsertItem(HC_ShowSplits, &p_ADlvi); // Using the lap time stamp/string for its name + + for (int c = 1; c <= cSectors; c++) // Now let's populate the sector times for Best Theoretical Lap + { + // Insert the item into the Listview + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = w; // Which Lap subscript + p_ADlvi.iSubItem = c; // Which Sector subscript incremented to be positioned correctly + p_ADlvi.lParam = c; + if ( i_TheoreticalBestLap[c] > 1 ) // 1 used for roundoff error + { + swprintf( result,NUMCHARS(result), L"%4.2f", i_TheoreticalBestLap[c] / 1000 ); + } + else + { + swprintf( result,NUMCHARS(result), L"", NULL); + } + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + ListView_SetItem(HC_ShowSplits, &p_ADlvi); + } + } + } + + void UpdateValues() + { + // Update the data channels that are being displayed as values + // List of highlighted laps + set setSelectedData = m_sfLapList.GetSelectedItemsData3(); + if(setSelectedData.size() > 0) + { + HWND hWndDataValues = GetDlgItem(m_hWnd, IDC_DATAVALUES); // Get the handle for the control + ListView_DeleteAllItems(hWndDataValues); // Clear the list before displaying the update + const int cLabels = 10; // The maximum number of Value Data channels to display, gated by display area + int i_WarningCoord[cLabels][3] = {NULL}; // Coordinates in the Data Channels display ListView for painting routines + bool m_Warning = false; // Flag for showing dialog of Value display to indicate statistics are outside of bounds + TCHAR m_szYString[512] = {NULL}; + TCHAR m_szWarningChannel[MAX_PATH] = {NULL}; + int w=0; // String variable counter for Vaue display + TCHAR szLabel[cLabels][MAX_PATH] = {NULL}; + // Loop through the selected Y-axis data channels for this lap + for(int x = 0; x < this->m_lstYChannels.size() && x < 49; x++) + { + const DATA_CHANNEL eChannel = m_lstYChannels[x]; + if(!eChannel /*|| !eChannel->IsValid()*/) continue; + float flMin, flMax, flAvg, flMinTemp, flMaxTemp; + // First check if this data channel is one to be displayed as a Value (false) or Graph (true) + for (int u = 0; u < sizeof m_lstYChannels; u++) + { + if (m_lstYChannels[x] == m_sfLapOpts.m_PlotPrefs[u].iDataChannel && m_sfLapOpts.m_PlotPrefs[u].iPlotView == true) + { + break; // Data channel is requested to be displayed as a graph, do nothing here + } + else if (m_lstYChannels[x] == m_sfLapOpts.m_PlotPrefs[u].iDataChannel && m_sfLapOpts.m_PlotPrefs[u].iPlotView == false) + { + // Let's get the statistical values for this channel for display + // go through all the laps we have selected to figure out min/max + flMin = 1e30; + flMax = -1e30; + float flVal; + for(set::const_iterator i = setSelectedData.begin(); i != setSelectedData.end(); i++) + { + CExtendedLap* pLap = (CExtendedLap*)*i; + const IDataChannel* pChannel = pLap->GetChannel(eChannel); + if (pChannel) // Check if pointer is valid + { + flVal = pChannel->GetValue(m_mapLapHighlightTimes[pLap]); + flMin = pChannel->GetMin(); + flMax = pChannel->GetMax(); + // 951turbo: do more math here like averages, median, etc. + flAvg = fAverage(eChannel, pChannel, flVal); + // See if the Minimum or Maximum are outside of the PlotPrefs setpoints +////////////////////////////////////////// + // Adding transformation functions here for Y + if (m_sfLapOpts.m_PlotPrefs[u].iTransformYesNo == true) + { + if (m_sfLapOpts.m_PlotPrefs[u].fTransBValue < 0) + { + flAvg = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flAvg * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flAvg * flAvg * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; + flMaxTemp = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flMin * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flMin * flMin * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; + flMinTemp = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flMax * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flMax * flMax * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; + } + else + { + flAvg = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flAvg * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flAvg * flAvg * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; + flMinTemp = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flMin * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flMin * flMin * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; + flMaxTemp = m_sfLapOpts.m_PlotPrefs[u].fTransAValue + flMax * m_sfLapOpts.m_PlotPrefs[u].fTransBValue + flMax * flMax * m_sfLapOpts.m_PlotPrefs[u].fTransCValue; + } + flMin = flMinTemp; + flMax = flMaxTemp; + } +////////////////////////////////////////// + if (flMax > m_sfLapOpts.m_PlotPrefs[u].fMaxValue) + { + m_Warning = true; // An alarm has been triggered! Save the channel name and post a warning dialog. + // Save the ListView coordinates for painting of this value + i_WarningCoord[w][2] = 1; // Maximum value exceeded + GetDataChannelName(eChannel,m_szWarningChannel,NUMCHARS(m_szWarningChannel)); // Get the failing channel name + // Build the failing channels string for output + swprintf(m_szYString,NUMCHARS(m_szYString),L"%s\n%s",m_szYString, m_szWarningChannel); + } + else if (flMin < m_sfLapOpts.m_PlotPrefs[u].fMinValue) + { + m_Warning = true; // An alarm has been triggered! Save the channel name and post a warning dialog. + // Save the ListView coordinates for painting of this value + i_WarningCoord[w][1] = -1; // Minimum value exceeded + GetDataChannelName(eChannel,m_szWarningChannel,NUMCHARS(m_szWarningChannel)); // Get the failing channel name + // Build the failing channels string for output + swprintf(m_szYString,NUMCHARS(m_szYString),L"%s\n%s",m_szYString, m_szWarningChannel); + } + else + { + // Reset the ListView coordinates for painting of this value + i_WarningCoord[w][1] = 0; // Reset Minimum value + i_WarningCoord[w][2] = 0; // Reset Maximum value + } + } + else + { + flVal=0.0f; + flMin=0.0f; + flMax=0.0f; + flAvg=0.0f; + // Reset the ListView coordinates for painting of this value + i_WarningCoord[w][1] = 0; // Reset Minimum value + i_WarningCoord[w][2] = 0; // Reset Maximum value + } + } + + // Now assign these values to the Data Value variable for display + TCHAR szChannelName[MAX_PATH]; + TCHAR w_szMin[MAX_PATH]; + TCHAR w_szMax[MAX_PATH]; + GetDataChannelName(eChannel,szChannelName,NUMCHARS(szChannelName)); + + char szMin[MAX_PATH]; + char szMax[MAX_PATH]; + GetChannelValue(eChannel,m_sfLapOpts.eUnitPreference,flMin,szMin,NUMCHARS(szMin)); + GetChannelValue(eChannel,m_sfLapOpts.eUnitPreference,flMax,szMax,NUMCHARS(szMax)); + // Need to convert these from char to wchar_t + swprintf(w_szMin, NUMCHARS(w_szMin), L"%S", szMin); + swprintf(w_szMax, NUMCHARS(w_szMax), L"%S", szMax); + + // Now display the results in the ListView (max of cLabels) + if (w < cLabels) + { + // Let's load the Listview row titles with this result + p_ADlvi.mask = LVIF_TEXT | LVIF_PARAM; + p_ADlvi.iItem = w; // Which Data Value subscript (Max = cLabels) + p_ADlvi.iSubItem = 0; // Which Sector subscript (0 = Lap Name string) + p_ADlvi.lParam = 0; + p_ADlvi.pszText = szChannelName; + p_ADlvi.cchTextMax = wcslen(szChannelName); + ListView_InsertItem(hWndDataValues, &p_ADlvi); + + wchar_t result[MAX_PATH] = {NULL}; // Null string + // Insert the item into the Listview + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = w; // Which Data Value subscript (Max = cLabels) + p_ADlvi.iSubItem = 1; // Which Subitem subscript + p_ADlvi.lParam = 1; + swprintf(result,NUMCHARS(result), L"%S", szMin); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + ListView_SetItem(hWndDataValues, &p_ADlvi); + + // Insert the item into the Listview + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = w; // Which Data Value subscript (Max = cLabels) + p_ADlvi.iSubItem = 2; // Which Subitem subscript + p_ADlvi.lParam = 2; + swprintf(result,NUMCHARS(result), L"%S", szMax); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + ListView_SetItem(hWndDataValues, &p_ADlvi); + + // Insert the item into the Listview + p_ADlvi.mask = LVIF_TEXT; + p_ADlvi.iItem = w; // Which Data Value subscript (Max = cLabels) + p_ADlvi.iSubItem = 3; // Which Subitem subscript + p_ADlvi.lParam = 3; + swprintf(result,NUMCHARS(result), L"%3.1f", flAvg); + p_ADlvi.pszText = result; + p_ADlvi.cchTextMax = wcslen(result); + ListView_SetItem(hWndDataValues, &p_ADlvi); + + w++; // Increment Value string counter + } + break; + } + else + { + } + } + } + if (m_Warning) // Pop up dialog saying the alarm has been triggered + { + static bool fWarnedOnce; // Prevent multiple windows from appearing + if(!fWarnedOnce) + { + // Display a warning dialog box about an alarm being triggered. + fWarnedOnce = true; + WARNING_RESULT sfResult; + CWarningDlg dlgWarning(&sfResult, m_szYString); + ArtShowDialog(&dlgWarning); + fWarnedOnce = false; + } + } + } + } +void UpdateDisplays() + { + m_sfLapPainter.Refresh(); + m_sfSubDisplay.Refresh(); +// if (m_sfLapOpts.bTractionCircle) +// { + m_sfTractionDisplay.Refresh(); +// } + } + void CheckMenuHelper(HMENU hMainMenu, int id, bool fChecked) + { + DWORD dwFlags = fChecked ? (MF_BYCOMMAND | MF_CHECKED) : (MF_BYCOMMAND | MF_UNCHECKED); + DWORD dwRet = CheckMenuItem(hMainMenu, id, dwFlags); + DASSERT(dwRet != -1); + } + void UpdateMenus() + { + HMENU hWndMenu = GetMenu(m_hWnd); + HMENU hSubMenu = GetSubMenu(hWndMenu, 2); // Graphing... menu + HMENU hSubMenu2 = GetSubMenu(hWndMenu, 3); // Phone Orientation... menu + + CheckMenuHelper(hSubMenu, ID_OPTIONS_KMH, m_sfLapOpts.eUnitPreference == UNIT_PREFERENCE_KMH); + CheckMenuHelper(hSubMenu, ID_OPTIONS_MPH, m_sfLapOpts.eUnitPreference == UNIT_PREFERENCE_MPH); + CheckMenuHelper(hSubMenu, ID_OPTIONS_MS, m_sfLapOpts.eUnitPreference == UNIT_PREFERENCE_MS); + CheckMenuHelper(hSubMenu, ID_OPTIONS_XAXIS_KM, m_sfLapOpts.bXAxis_KM == XAXIS_PREFERENCE_KM); + CheckMenuHelper(hSubMenu, ID_OPTIONS_XAXIS_LAT, m_sfLapOpts.bXAxis_KM == XAXIS_PREFERENCE_LAT); + CheckMenuHelper(hSubMenu, ID_OPTIONS_TRACTIONCIRCLE, m_sfLapOpts.bTractionCircle); + CheckMenuHelper(hSubMenu, ID_OPTIONS_SHOWBESTS, m_fShowBests); + CheckMenuHelper(hSubMenu, ID_OPTIONS_SHOWDRIVERBESTS, m_fShowDriverBests); + CheckMenuHelper(hSubMenu, ID_OPTIONS_SHOWREFERENCELAP, m_fShowReferenceLap); + CheckMenuHelper(hSubMenu, ID_OPTIONS_DRAWLINES, m_sfLapOpts.fDrawLines); + CheckMenuHelper(hSubMenu, ID_OPTIONS_SMOOTH, m_sfLapOpts.bSmoothYesNo); + CheckMenuHelper(hSubMenu, ID_OPTIONS_BACKGROUND, m_sfLapOpts.fColorScheme); + CheckMenuHelper(hSubMenu, ID_OPTIONS_IOIO5VSCALE, m_sfLapOpts.fIOIOHardcoded); + CheckMenuHelper(hSubMenu, ID_OPTIONS_ELAPSEDTIME, m_sfLapOpts.fElapsedTime); + CheckMenuHelper(hSubMenu2, ID_OPTIONS_VERTICAL_LANDSCAPE, m_sfLapOpts.e_Orientation == VERTICAL_LANDSCAPE); + CheckMenuHelper(hSubMenu2, ID_OPTIONS_VERTICAL_PORTRAIT, m_sfLapOpts.e_Orientation == VERTICAL_PORTRAIT); + CheckMenuHelper(hSubMenu2, ID_OPTIONS_FLAT_LANDSCAPE, m_sfLapOpts.e_Orientation == FLAT_LANDSCAPE); + CheckMenuHelper(hSubMenu2, ID_OPTIONS_FLAT_PORTRAIT, m_sfLapOpts.e_Orientation == FLAT_PORTRAIT); + } + + vector GetSortedLaps(LAPSORTSTYLE eSortStyle) + { + vector lstLaps; + for(map::iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) + { + lstLaps.push_back(i->second); + } + switch(eSortStyle) + { + case SORTSTYLE_BYTIMEOFRACE: + sort(lstLaps.begin(),lstLaps.end(), CExtendedLap_SortByTime); + break; + case SORTSTYLE_BYLAPTIME: + sort(lstLaps.begin(),lstLaps.end(), CExtendedLap_SortByLapTime); + break; + } + return lstLaps; + } + + void LoadLaps(ILapReceiver* pReceiver) + { + int z_iRaceId = 0; + for (int z = 0; z < 50; z++) + { + if (m_iRaceId[z] <= 0) break; // Only load the valid Race Id's + z_iRaceId = m_iRaceId[z]; + vector laps = pReceiver->GetLaps(z_iRaceId); + for(int x = 0;x < laps.size(); x++) + { + const ILap* pLap = laps[x]; + // let's see if we already have this lap + if(m_mapLaps.count(pLap->GetLapId()) != 0) + { + // we've already got this lap. THere is nothing to be added from this lap + ((ILap*)pLap)->Free(); + laps[x] = NULL; + } + else + { + // we don't have this lap yet, so let's put it in + CExtendedLap* pNewLap = new CExtendedLap(pLap, m_pReferenceLap, pReceiver, true); + if(m_pReferenceLap == NULL) // If there is no reference lap currently + { + m_pReferenceLap = pNewLap; // by default, make the first lap received the reference lap + } + if(pLap->GetComment().size() <= 0) + { + pLap->SetComment(m_szCommentText); + } + m_mapLaps[pLap->GetLapId()] = pNewLap; + } + } + } + } + + void ApplyDriverNameToSelectedLaps(ILapReceiver* pLapDB) + { + set setSelectedData = m_sfLapList.GetSelectedItemsData3(); + for(set::iterator i = setSelectedData.begin(); i != setSelectedData.end(); i++) + { + // the ints of this set are actually pointers to CExtendedLap objects + CExtendedLap* pLap = (CExtendedLap*)(*i); + pLap->GetLap()->SetComment(m_szCommentText); + } + } + + virtual void SetLapHighlightTime(const CExtendedLap* pLap, int iTimeMs) override + { + m_mapLapHighlightTimes[pLap] = iTimeMs; + } + virtual int GetLapHighlightTime(const CExtendedLap* pLap) const override + { + DASSERT(m_mapLapHighlightTimes.find(pLap) != m_mapLapHighlightTimes.end()); // this should have always ended up set from the "master" highlighter. This function is only called by "slave" highlight-users + return m_mapLapHighlightTimes.find(pLap)->second; + } + virtual bool IsHighlightSource(int iSupplierId) const override + { + switch(iSupplierId) + { + case SUPPLIERID_MAINDISPLAY: + return true; // main display is always the driver of highlight data + case SUPPLIERID_SUBDISPLAY: + return false; + case SUPPLIERID_SECTORDISPLAY: + return true; // Allow the Set Split Sectors to be highlight source + case SUPPLIERID_TRACTIONCIRCLEDISPLAY: + case SUPPLIERID_ALLDATADISPLAY: + return false; // main display is always the driver of highlight data + default: + DASSERT(FALSE); + return false; + } + } + + virtual vector GetAllLaps() const override + { + set setSelectedLaps = m_sfLapList.GetSelectedItemsData3(); + vector lstLaps; + for(map::const_iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) + { + CExtendedLap* pLap = i->second; + lstLaps.push_back(pLap); + } + + return lstLaps; + } + virtual vector GetLapsToShow() const override + { + set setSelectedLaps = m_sfLapList.GetSelectedItemsData3(); + vector lstLaps; + map mapFastestDriver; + CExtendedLap* pFastest = NULL; + CExtendedLap* pReference = NULL; // Added to show Reference Lap - KDJ + for(set::iterator i = setSelectedLaps.begin(); i != setSelectedLaps.end(); i++) + { + CExtendedLap* pLap = (CExtendedLap*)*i; + + lstLaps.push_back(pLap); + } + + for(map::const_iterator i = m_mapLaps.begin(); i != m_mapLaps.end(); i++) + { + CExtendedLap* pLap = i->second; + if(m_fShowDriverBests && (mapFastestDriver.count(pLap->GetLap()->GetComment()) == 0 || pLap->GetLap()->GetTime() < mapFastestDriver[pLap->GetLap()->GetComment()]->GetLap()->GetTime())) + { + mapFastestDriver[pLap->GetLap()->GetComment()] = pLap; + } + if(m_fShowBests) + { + if(pFastest == NULL || pLap->GetLap()->GetTime() < pFastest->GetLap()->GetTime()) + { + pFastest = pLap; + } + } + } + + if(m_fShowBests && pFastest) + { + lstLaps.push_back(pFastest); + } + for(map::iterator i = mapFastestDriver.begin(); i != mapFastestDriver.end(); i++) + { + lstLaps.push_back(i->second); + } + + // Set up for showing Reference lap similar to how we show Fastest Lap. + if(m_fShowReferenceLap && m_pReferenceLap != NULL) + { + lstLaps.push_back(m_pReferenceLap); + } +/* else + { + lstLaps.push_back(m_pReferenceLap); // Push the reference lap anyway, so that we can get the lap Split Points + } +*/ + + return lstLaps; + } + virtual FLOATRECT GetAllLapsBounds() const override + { + FLOATRECT rc; + rc.left = 1e30; + rc.top = -1e30; + rc.bottom = 1e30; + rc.right = -1e30; + + // changed this so it returns the bounds of the reference lap. This way, data-viewing isn't ruined by errant points + // it used to be based on all the laps, but if you had just one messed-up lap it would make viewing pointless + if(m_pReferenceLap != NULL) + { + const vector& lstPoints = m_pReferenceLap->GetPoints(); + for(int x = 0; x< lstPoints.size(); x++) + { + const TimePoint2D& p = lstPoints[x]; + rc.left = min(rc.left,p.flX); + rc.top = max(rc.top,p.flY); + rc.bottom = min(rc.bottom,p.flY); + rc.right = max(rc.right,p.flX); + } + + rc.left += m_flShiftX; + rc.top += m_flShiftY; + rc.right += m_flShiftX; + rc.bottom += m_flShiftY; + } + return rc; + } + virtual LAPDISPLAYSTYLE GetLapDisplayStyle(int iSupplierId) const override + { + switch(iSupplierId) + { + case SUPPLIERID_MAINDISPLAY: + { + vector lstLaps = GetLapsToShow(); + if(lstLaps.size() <= 0) return LAPDISPLAYSTYLE_NOLAPS; + return m_eLapDisplayStyle; + } + case SUPPLIERID_SUBDISPLAY: + switch(m_eLapDisplayStyle) + { + case LAPDISPLAYSTYLE_MAP: return LAPDISPLAYSTYLE_PLOT; + default: return LAPDISPLAYSTYLE_MAP; + } + case SUPPLIERID_TRACTIONCIRCLEDISPLAY: + { + return LAPDISPLAYSTYLE_TRACTIONCIRCLE; + } + case SUPPLIERID_ALLDATADISPLAY: + { + return LAPDISPLAYSTYLE_ALLDATADISPLAY; + } + case SUPPLIERID_SECTORDISPLAY: + { + return LAPDISPLAYSTYLE_MAP; + } + default: + DASSERT(FALSE); + break; + } + return m_eLapDisplayStyle; + } + virtual float GetDataHardcodedMin(DATA_CHANNEL eChannel) const override + { + if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || + eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END || + eChannel >= DATA_CHANNEL_RACEDAC_START && eChannel < DATA_CHANNEL_RACEDAC_END || + eChannel >= DATA_CHANNEL_RACEDACCUSTOM_START && eChannel < DATA_CHANNEL_RACEDACCUSTOM_END) + { + return m_sfLapOpts.fIOIOHardcoded ? 0 : 1e30; + } + return 1e30; + } + virtual float GetDataHardcodedMax(DATA_CHANNEL eChannel) const override + { + if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || + eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END || + eChannel >= DATA_CHANNEL_RACEDAC_START && eChannel < DATA_CHANNEL_RACEDAC_END || + eChannel >= DATA_CHANNEL_RACEDACCUSTOM_START && eChannel < DATA_CHANNEL_RACEDACCUSTOM_END) + { + return m_sfLapOpts.fIOIOHardcoded ? 5 : -1e30; + } + return -1e30; + } + + virtual float GetGuideStartX(DATA_CHANNEL eChannel, float flMin, float flMax) override + { + CASSERT(DATA_CHANNEL_COUNT == 0x601); + + switch(eChannel) + { + case DATA_CHANNEL_X: return 1e30; + case DATA_CHANNEL_Y: return 1e30; // we don't want guides for either latitude or longitude + case DATA_CHANNEL_VELOCITY: + case DATA_CHANNEL_VELOCITYDELTA: + { + int iMin = (int)(flMin); + return (float)(iMin); + } + case DATA_CHANNEL_DISTANCE: + { + int iMin = (int)(flMin); + return (float)(iMin); + } + case DATA_CHANNEL_TIME: + case DATA_CHANNEL_ELAPSEDTIME: + case DATA_CHANNEL_TIMESLIP: + case DATA_CHANNEL_LAPTIME_SUMMARY: + { + int iMin = (int)(flMin/1000.0f); + return (float)(iMin)*1000.0f; + } + case DATA_CHANNEL_X_ACCEL: + case DATA_CHANNEL_Y_ACCEL: + case DATA_CHANNEL_Z_ACCEL: + { + int iMin = (int)(flMin); + return (float)(iMin); + } + case DATA_CHANNEL_TEMP: return 0; + case (DATA_CHANNEL_PID_START+0x5): return -40; + case (DATA_CHANNEL_PID_START+0xc): return 0; + case (DATA_CHANNEL_PID_START+0xA): return 0; + case (DATA_CHANNEL_PID_START+0x5c): return -40; + default: + if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || + eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END || + eChannel >= DATA_CHANNEL_RACEDAC_START && eChannel < DATA_CHANNEL_RACEDAC_END || + eChannel >= DATA_CHANNEL_RACEDACCUSTOM_START && eChannel < DATA_CHANNEL_RACEDACCUSTOM_END) + { + return m_sfLapOpts.fIOIOHardcoded ? 0 : 1e30; + } + return 1e30; + } + } + + virtual float GetGuideStart(DATA_CHANNEL eChannel, float flMin, float flMax) override + { + CASSERT(DATA_CHANNEL_COUNT == 0x601); + + switch(eChannel) + { + case DATA_CHANNEL_X: return 1e30; + case DATA_CHANNEL_Y: return 1e30; // we don't want guides for either latitude or longitude + case DATA_CHANNEL_VELOCITY: return 0; + case DATA_CHANNEL_DISTANCE: return 1e30; + case DATA_CHANNEL_TIME: + case DATA_CHANNEL_ELAPSEDTIME: + case DATA_CHANNEL_TIMESLIP: + { + int iMin = (int)(flMin/1000.0f); + return (float)(iMin)*1000.0f; + } + case DATA_CHANNEL_STRENGTH: return 0.0f; + case DATA_CHANNEL_LAPTIME_SUMMARY: + case DATA_CHANNEL_X_ACCEL: + case DATA_CHANNEL_Y_ACCEL: + case DATA_CHANNEL_Z_ACCEL: + { + int iMin = (int)(flMin); + return (float)(iMin); + } + case DATA_CHANNEL_VELOCITYDELTA: + { + int iMin = (int)(flMin); + return (float)(iMin); + } + case DATA_CHANNEL_TEMP: return 0; + + default: + if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || + eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END || + eChannel >= DATA_CHANNEL_RACEDAC_START && eChannel < DATA_CHANNEL_RACEDAC_END || + eChannel >= DATA_CHANNEL_RACEDACCUSTOM_START && eChannel < DATA_CHANNEL_RACEDACCUSTOM_END) + { + return m_sfLapOpts.fIOIOHardcoded ? 0 : 1e30; + } + else if(eChannel >= DATA_CHANNEL_PID_START && eChannel < DATA_CHANNEL_PID_END) + { + int iMin = (int)(flMin); + return (float)(iMin); + } + return 1e30; + } + } + + virtual float GetGuideStepX(DATA_CHANNEL eChannel, float flMin, float flMax) override + { + // Function sets up the spacing for the vertical guidelines on the data plots + CASSERT(DATA_CHANNEL_COUNT == 0x601); + const float flSpread = flMax - flMin; + switch(eChannel) + { + case DATA_CHANNEL_X: return 1e30; + case DATA_CHANNEL_Y: return 1e30; // we don't want guides for either latitude or longitude + case DATA_CHANNEL_VELOCITY: // We need to fix the X-channel call before putting these back into the code. + case DATA_CHANNEL_VELOCITYDELTA: + { + switch(m_sfLapOpts.eUnitPreference) + { + case UNIT_PREFERENCE_KMH: return KMH_TO_MS(25.0); + case UNIT_PREFERENCE_MPH: return MPH_TO_MS(20.0); // Adjusted by KDJ + case UNIT_PREFERENCE_MS: return 5; + } + return 10.0; + } + case DATA_CHANNEL_DISTANCE: + { + if(flSpread < 0.001) return 0.0001f; + if(flSpread < 0.005) return 0.0005f; + if(flSpread < 0.010) return 0.0010f; + if(flSpread < 0.050) return 0.0050f; + if(flSpread < 1.000) return 0.1000f; + if(flSpread < 10.00) return 1.0000f; + if(flSpread < 500) return 50.0f; + if(flSpread < 1000) return 100.0f; + if(flSpread < 5000) return 500.0f; + if(flSpread < 10000) return 1000.0f; + if(flSpread < 50000) return 2500.0f; + if(flSpread < 110000) return 5000.0f; + if(flSpread < 1100000) return 10000.0f; + if(flSpread < 10000000) return 100000.0f; + return 10000000; + } + + case DATA_CHANNEL_TIME: + case DATA_CHANNEL_ELAPSEDTIME: + { + if(flSpread < 1000) return 50.0f; + if(flSpread < 5000) return 100.0f; + if(flSpread < 10000) return 500.0f; + if(flSpread < 50000) return 2500.0f; + if(flSpread < 110000) return 5000.0f; + if(flSpread < 1100000) return 10000.0f; + if(flSpread < 10000000) return 100000.0f; + if(flSpread < 100000000) return 1000000.0f; + return 10000000.0f; + } + case DATA_CHANNEL_LAPTIME_SUMMARY: + { + if(flSpread < 1) return 0.50f; + if(flSpread < 5) return 1.0f; + if(flSpread < 10) return 5.0f; + if(flSpread < 50) return 25.0f; + if(flSpread < 110) return 50.0f; + if(flSpread < 1100) return 100.0f; + if(flSpread < 10000) return 1000.0f; + if(flSpread < 50000) return 2500.0f; + if(flSpread < 110000) return 5000.0f; + if(flSpread < 1100000) return 10000.0f; + if(flSpread < 10000000) return 100000.0f; + if(flSpread < 100000000) return 1000000.0f; + return 10000000.0f; + } + default: + return 1e30; + } + } + + virtual float GetGuideStep(DATA_CHANNEL eChannel, float flMin, float flMax) override + { + CASSERT(DATA_CHANNEL_COUNT == 0x601); + const float flSpread = flMax - flMin; + switch(eChannel) + { + case DATA_CHANNEL_X: return 1e30; + case DATA_CHANNEL_Y: return 1e30; // we don't want guides for either latitude or longitude + case DATA_CHANNEL_VELOCITY: + { + switch(m_sfLapOpts.eUnitPreference) + { + case UNIT_PREFERENCE_KMH: return KMH_TO_MS(25.0); + case UNIT_PREFERENCE_MPH: return MPH_TO_MS(20.0); // Adjusted by KDJ + case UNIT_PREFERENCE_MS: return 5; + } + return 10.0; + } + case DATA_CHANNEL_VELOCITYDELTA: + { + if(flSpread < 1) return 0.5f; + if(flSpread < 5) return 1.0f; + if(flSpread < 10) return 2.0f; + if(flSpread < 20) return 5.0f; + if(flSpread < 40) return 10.0f; + if(flSpread < 60) return 15.0f; + if(flSpread < 100) return 20.0f; + return 2.0; + } + case DATA_CHANNEL_DISTANCE: + { + if(flSpread < 0.001) return 0.0001f; + if(flSpread < 0.005) return 0.0005f; + if(flSpread < 0.010) return 0.0010f; + if(flSpread < 0.050) return 0.0050f; + if(flSpread < 1.000) return 0.1000f; + if(flSpread < 10.00) return 1.0000f; + if(flSpread < 1000) return 100.0f; + if(flSpread < 5000) return 500.0f; + if(flSpread < 10000) return 1000.0f; + if(flSpread < 50000) return 5000.0f; + if(flSpread < 110000) return 10000.0f; + if(flSpread < 1100000) return 100000.0f; + if(flSpread < 10000000) return 1000000.0f; + return 10000000; + } + + case DATA_CHANNEL_TIME: return 1e30; // No guidelines for Y-axis + case DATA_CHANNEL_TIMESLIP: + case DATA_CHANNEL_ELAPSEDTIME: + { + if(flSpread < 10) return 1.0f; + if(flSpread < 100) return 10.0f; + if(flSpread < 1000) return 100.0f; + if(flSpread < 5000) return 500.0f; + if(flSpread < 10000) return 1000.0f; + if(flSpread < 50000) return 5000.0f; + if(flSpread < 110000) return 10000.0f; + if(flSpread < 1100000) return 100000.0f; + if(flSpread < 10000000) return 1000000.0f; + return 10000000.0f; + } + case DATA_CHANNEL_LAPTIME_SUMMARY: + { + if(flSpread < 5) return 0.5f; + if(flSpread < 10) return 1.0f; + if(flSpread < 50) return 5.0f; + if(flSpread < 100) return 10.0f; + if(flSpread < 1100) return 100.0f; + if(flSpread < 10000) return 1000.0f; + if(flSpread < 50000) return 5000.0f; + if(flSpread < 110000) return 10000.0f; + if(flSpread < 1100000) return 100000.0f; + if(flSpread < 10000000) return 1000000.0f; + return 10000000.0f; + } + case DATA_CHANNEL_X_ACCEL: return 0.5f; + case DATA_CHANNEL_Y_ACCEL: return 0.5f; + case DATA_CHANNEL_Z_ACCEL: return 0.5f; + case DATA_CHANNEL_TEMP: return 10.0f; + case DATA_CHANNEL_STRENGTH: return 1.0f; + + default: + if(eChannel >= DATA_CHANNEL_IOIOPIN_START && eChannel < DATA_CHANNEL_IOIOPIN_END || + eChannel >= DATA_CHANNEL_IOIOCUSTOM_START && eChannel < DATA_CHANNEL_IOIOCUSTOM_END || + eChannel >= DATA_CHANNEL_RACEDAC_START && eChannel < DATA_CHANNEL_RACEDAC_END || + eChannel >= DATA_CHANNEL_RACEDACCUSTOM_START && eChannel < DATA_CHANNEL_RACEDACCUSTOM_END) + { + if(flSpread < 1) return m_sfLapOpts.fIOIOHardcoded ? 0.1f : 1e30; + if(flSpread < 10) return m_sfLapOpts.fIOIOHardcoded ? 1.0f : 1e30; + if(flSpread < 25) return m_sfLapOpts.fIOIOHardcoded ? 2.5f : 1e30; + if(flSpread < 50) return m_sfLapOpts.fIOIOHardcoded ? 5.0f : 1e30; + if(flSpread < 150) return m_sfLapOpts.fIOIOHardcoded ? 20.0f : 1e30; + if(flSpread < 500) return m_sfLapOpts.fIOIOHardcoded ? 50.0f : 1e30; + if(flSpread < 10000) return m_sfLapOpts.fIOIOHardcoded ? 1000.0f : 1e30; + if(flSpread < 100000) return m_sfLapOpts.fIOIOHardcoded ? 5000.0f : 1e30; + if(flSpread < 1000000) return m_sfLapOpts.fIOIOHardcoded ? 50000.0f : 1e30; + return m_sfLapOpts.fIOIOHardcoded ? 1.0f : 1e30; // Original code, and default for non-transformed IOIO data + } + else if(eChannel >= DATA_CHANNEL_PID_START && eChannel < DATA_CHANNEL_PID_END) + { + if(flSpread < 1) return 0.1f; + if(flSpread < 10) return 1.0f; + if(flSpread < 25) return 2.5f; + if(flSpread < 50) return 5.0f; + if(flSpread < 150) return 20.0f; + if(flSpread < 500) return 50.0f; + if(flSpread < 10000) return 1000.0f; + if(flSpread < 100000) return 5000.0f; + if(flSpread < 1000000) return 50000.0f; + return 1e30; + } + return 1e30; + } + } + virtual const LAPSUPPLIEROPTIONS& GetDisplayOptions() const override + { + return m_sfLapOpts; + } + virtual DATA_CHANNEL GetXChannel() const override + { + return m_eXChannel; + } + virtual const IDataChannel* GetChannel(int iLapId, DATA_CHANNEL eChannel) const override + { + return g_pLapDB->GetDataChannel(iLapId, eChannel); + } + virtual vector GetYChannels() const override + { + return m_lstYChannels; + } + virtual void GetResponse(const char* pbData, int cbData, char** ppbResponse, int* pcbResponse) + { + + } + void SetupMulticast() + { + IP_ADAPTER_INFO sfAdapter[255] = {0}; + ULONG cbAdapter = sizeof(sfAdapter); + ULONG ret = GetAdaptersInfo(sfAdapter, &cbAdapter); + int cConnected = 0; + if(ret == NO_ERROR) + { + IP_ADAPTER_INFO* pInfo = &sfAdapter[0]; + while(pInfo) + { + if(strcmp(pInfo->IpAddressList.IpAddress.String, "0.0.0.0") != 0) + { + // found an adapter. That means we need a multicast checker + MulticastListener* pListener = new MulticastListener(&m_sfResponder, pInfo->IpAddressList.IpAddress.String); + if(pListener->Start()) + { + m_lstMulticast.push_back(pListener); + } + else + { + delete pListener; + } + } + + pInfo = pInfo->Next; + } + } + } +public: + vector m_lstYChannels; + DATA_CHANNEL m_eXChannel; // Made public by KDJ + ArtListBox m_sfYAxis; + CExtendedLap* m_pReferenceLap; + ArtListBox m_sfLapList; + ArtListBox m_sfListBox; + int m_iRaceId[50]; // Made public by KDJ +private: + ArtListBox m_sfXAxis; + + CLapPainter m_sfLapPainter; +// CLapPainter m_sfSubWindow; + CLapPainter m_sfSubDisplay; + CLapPainter m_sfTractionDisplay; + + // lap display style data + map m_mapLapHighlightTimes; // stores the highlight times (in milliseconds since phone app start) for each lap. Set from ILapSupplier calls + + LAPDISPLAYSTYLE m_eLapDisplayStyle; +// DATA_CHANNEL m_eXChannel; +// vector m_lstYChannels; + bool m_fShowTractionCircle; + bool m_fSmooth; + bool m_fShowBests; + bool m_fShowDriverBests; + bool m_fShowReferenceLap; + +// CExtendedLap* m_pReferenceLap; // Made public by KDJ + map m_mapLaps; // maps from iLapId to a lap object + HWND m_hWnd; + + map m_baseWindowPos; + + TCHAR m_szCommentText[512]; + TCHAR m_szMessageStatus[512]; + + // what updates are needed. When we call UpdateUI, it will |= the requested flags onto this, and then do a PostMessage with a custom UPDATEUI message + // when the UPDATEUI message is received, it will do an UpdateUI_Internal call using all the flags that have been built up, and clear the ones it handled. + DWORD m_fdwUpdateNeeded; + + // panning/zooming + float m_flShiftX; + float m_flShiftY; + + // multicast responses for each network device detected + vector m_lstMulticast; + MCResponder m_sfResponder; + +// int m_iRaceId[50]; + ILapSupplier* z_ILapSupplier; +}; + +DWORD ReceiveThreadProc(LPVOID param) +{ + ILapReceiver* pLaps = (ILapReceiver*)param; +// bool b_receive_data = pLaps->m_Button_LiveData(); + while(true) + { + ReceiveLaps(63939, pLaps); + } + return 0; +} + +int str_ends_with(const TCHAR * str, const TCHAR * suffix) +{ + if( str == NULL || suffix == NULL ) + return 0; + + size_t str_len = wcslen(str); + size_t suffix_len = wcslen(suffix); + + if(suffix_len > str_len) + return 0; + + return 0 == wcsncmp( str + str_len - suffix_len, suffix, suffix_len ); +} + +void LoadPitsideSettings(PITSIDE_SETTINGS* pSettings) +{ + pSettings->Default(); + + TCHAR szModule[MAX_PATH]; + if(GetAppFolder(szModule,NUMCHARS(szModule))) + { + wcsncat(szModule,L"settings.txt", NUMCHARS(szModule)); + + ifstream in; + in.open(szModule); + if(!in.eof() && !in.fail()) + { + in>>pSettings->fRunHTTP; + in>>pSettings->iHTTPPort; + in>>pSettings->iVelocity; + in>>pSettings->iMapLines; + in>>pSettings->iColorScheme; + in>>pSettings->bSmoothYesNo; + in>>pSettings->bXAxis_KM; + in.close(); + } + } + else + { + // trouble. just bail. + return; + } +} + +void InitPlotPrefs(LAPSUPPLIEROPTIONS &p_sfLapOpts) + { for (int i=0; i < 50; i++) { - swprintf(p_sfLapOpts.m_PlotPrefs[i].m_ChannelName, L"Velocity"); - p_sfLapOpts.m_PlotPrefs[i].iDataChannel = DATA_CHANNEL_VELOCITY; - p_sfLapOpts.m_PlotPrefs[i].iPlotView = true; // Default to dsplay as a graph - p_sfLapOpts.m_PlotPrefs[i].fMinValue = -3.0; // Set all lower limits to -3.0 - p_sfLapOpts.m_PlotPrefs[i].fMaxValue = 1000000.0; // Set all upper limits to 1000000.0 - p_sfLapOpts.m_PlotPrefs[i].iTransformYesNo = false; // Default to display as a graph - p_sfLapOpts.m_PlotPrefs[i].fTransAValue = 0.0; // Set all A constants to 0.0 - p_sfLapOpts.m_PlotPrefs[i].fTransBValue = 1.0; // Set all B constants to 1.0 - p_sfLapOpts.m_PlotPrefs[i].fTransCValue = 0.0; // Set all C constants to 0.0 - p_sfLapOpts.m_SplitPoints[i].m_sfXPoint = 0.0f; // Initialize all split points - p_sfLapOpts.m_SplitPoints[i].m_sfYPoint = 0.0f; // Initialize all split points - p_sfLapOpts.m_SplitPoints[i].m_sfSectorTime = 0; // Initialize all sector times - p_sfLapOpts.m_SplitPoints[i].m_sfSplitTime = 0.0f; - p_sfLapOpts.fDrawSplitPoints = false; // Default to not show split points - p_sfLapOpts.m_Tranformations[i].f_CoeffA= -1.0; - p_sfLapOpts.m_Tranformations[i].f_CoeffB= -1.0; - p_sfLapOpts.m_Tranformations[i].f_CoeffC= -1.0; - swprintf(p_sfLapOpts.m_Tranformations[i].c_Name, L""); - p_sfLapOpts.m_Tranformations[i].b_LoadTrans = false; + swprintf(p_sfLapOpts.m_PlotPrefs[i].m_ChannelName, L"Velocity"); + p_sfLapOpts.m_PlotPrefs[i].iDataChannel = DATA_CHANNEL_VELOCITY; + p_sfLapOpts.m_PlotPrefs[i].iPlotView = true; // Default to dsplay as a graph + p_sfLapOpts.m_PlotPrefs[i].fMinValue = -3.0; // Set all lower limits to -3.0 + p_sfLapOpts.m_PlotPrefs[i].fMaxValue = 1000000.0; // Set all upper limits to 1000000.0 + p_sfLapOpts.m_PlotPrefs[i].iTransformYesNo = false; // Default to display as a graph + p_sfLapOpts.m_PlotPrefs[i].fTransAValue = 0.0; // Set all A constants to 0.0 + p_sfLapOpts.m_PlotPrefs[i].fTransBValue = 1.0; // Set all B constants to 1.0 + p_sfLapOpts.m_PlotPrefs[i].fTransCValue = 0.0; // Set all C constants to 0.0 + p_sfLapOpts.m_SplitPoints[i].m_sfXPoint = 0.0f; // Initialize all split points + p_sfLapOpts.m_SplitPoints[i].m_sfYPoint = 0.0f; // Initialize all split points + p_sfLapOpts.m_SplitPoints[i].m_sfSectorTime = 0; // Initialize all sector times + p_sfLapOpts.m_SplitPoints[i].m_sfSplitTime = 0.0f; + p_sfLapOpts.fDrawSplitPoints = false; // Default to not show split points + p_sfLapOpts.m_Tranformations[i].f_CoeffA= -1.0; + p_sfLapOpts.m_Tranformations[i].f_CoeffB= -1.0; + p_sfLapOpts.m_Tranformations[i].f_CoeffC= -1.0; + swprintf(p_sfLapOpts.m_Tranformations[i].c_Name, L""); + p_sfLapOpts.m_Tranformations[i].b_LoadTrans = false; + } + } + +void SaveSettings(TCHAR szDBPath[MAX_PATH], PITSIDE_SETTINGS* sfSettings, CMainUI* sfUI) +{ + TCHAR szTempPath[MAX_PATH]; + if(GetTempPathW(NUMCHARS(szTempPath),szTempPath)) + { + wcscat(szTempPath,L"LatestSettings.txt"); + + wofstream out; + out.open(szTempPath); + if(!out.eof() && !out.fail()) + { + out << sfUI->m_szPath << endl; // The file name for the database + for (int t=0; t<50; t++) // Save the RaceID's currently displayed + { + out << sfUI->m_iRaceId[t] << endl; + } + out << sfSettings->fRunHTTP << endl; + out << sfSettings->iHTTPPort << endl; + out << sfSettings->iVelocity << endl; + out << sfSettings->iMapLines << endl; + out << sfSettings->iColorScheme << endl; + out << sfSettings->bSmoothYesNo << endl; + out << sfSettings->bXAxis_KM << endl; + + out << sfUI->m_sfLapOpts.bShowReferenceLap << endl; + out << sfUI->m_sfLapOpts.bSmoothYesNo << endl; + out << sfUI->m_sfLapOpts.bTractionCircle << endl; + out << sfUI->m_sfLapOpts.bXAxis_KM << endl; + out << sfUI->m_sfLapOpts.eSortPreference << endl; + out << sfUI->m_sfLapOpts.eUnitPreference << endl; + out << sfUI->m_sfLapOpts.e_Orientation << endl; + out << sfUI->m_sfLapOpts.fColorScheme << endl; + out << sfUI->m_sfLapOpts.fDrawGuides << endl; + out << sfUI->m_sfLapOpts.fDrawLines << endl; + out << sfUI->m_sfLapOpts.fDrawSplitPoints << endl; + out << sfUI->m_sfLapOpts.fElapsedTime << endl; + out << sfUI->m_sfLapOpts.fIOIOHardcoded << endl; + out << sfUI->m_sfLapOpts.flWindowShiftX << endl; + out << sfUI->m_sfLapOpts.flWindowShiftY << endl; + out << sfUI->m_sfLapOpts.iZoomLevels << endl; + + for (int i=0; i < 50; i++) + { + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].iDataChannel << endl; // Save the Data Channel number + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].m_ChannelName << endl; // Save the Data Channel Name + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].iPlotView << endl; // Save how channel is displayed (graph/value) + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].fMinValue << endl; // Save the lower limit for the Alarm + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].fMaxValue << endl; // Save the upper limit for the Alarm + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].iTransformYesNo << endl; // Save whether channel is transformed + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].fTransAValue << endl; // Save A constants + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].fTransBValue << endl; // Save B constants + out << sfUI->m_sfLapOpts.m_PlotPrefs[i].fTransCValue << endl; // Save C constants + out << sfUI->m_sfLapOpts.m_SplitPoints[i].m_sfXPoint << endl; // Save split points + out << sfUI->m_sfLapOpts.m_SplitPoints[i].m_sfYPoint << endl; // Save split points + out << sfUI->m_sfLapOpts.m_SplitPoints[i].m_sfSectorTime << endl; // Save sector times + out << sfUI->m_sfLapOpts.m_SplitPoints[i].m_sfSplitTime << endl; // Save best sector time + } + out << "End of Plot Prefs" << endl; + + out << sfUI->m_sfLapOpts.fDrawSplitPoints << endl; // Save setting to show/hide split points + if ( sfUI->m_pReferenceLap ) + out << sfUI->m_pReferenceLap->m_pLap->GetLapId() << endl; // Save the Reference Lap ID + else + out << "0" << endl; + + out << sfUI->m_eXChannel << endl; // Save X-Axis data channel + for (int i=0; i < sfUI->m_lstYChannels.size(); i++) // Save the list of selected Y-Axis channels + { + out << sfUI->m_lstYChannels[i] << endl; // Save the list of selected Y-Axis channels + } + out << "//" << endl; // End of file marker + out.close(); + } + + } +} + +int LoadSettings(TCHAR szDBPath[MAX_PATH], PITSIDE_SETTINGS* sfSettings, CMainUI* sfUI) +{ + TCHAR szTempPath[MAX_PATH]; + if(GetTempPathW(NUMCHARS(szTempPath),szTempPath)) + { + wcscat(szTempPath,L"LatestSettings.txt"); + + vector lines; + ifstream in; + in.open(szTempPath); + // Read in all of the lines of the "LatestSettings.txt" file at once, or it doesn't work right + // Store them in the 'lines' vector + for (int i = 0; i < 1000; i++) + { + string Line; + if(!in.eof() && !in.fail()) + { + getline(in, Line); + if (Line != "//") + { + lines.push_back(Line); + } + else + { + break; + } + } + else + { + break; + } + } + in.close(); + + // Now let's process the information and load it in the sfUI data structure + string Line = lines[0]; + int t; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + swprintf(sfUI->m_szPath, NUMCHARS(sfUI->m_szPath), c_Name); // Load name of last-processed file in sfUI Pointer for szDBPath + } + for (t=1; t<=50; t++) // Load the RaceID's to be displayed + { + Line = lines[t]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_iRaceId[t-1] = _wtoi(c_Name); // Load the last Race session ID's into Pitside Console for loading and display + } + } + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfSettings->fRunHTTP = _wtoi(c_Name); // Load the boolean on whether to run the HTTP server into sfSettings data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfSettings->iHTTPPort = _wtoi(c_Name); // Load the HTTP port number into sfSettings data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfSettings->iVelocity = _wtoi(c_Name); // Load the Velocity (km/mi/mps) into sfSettings data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfSettings->iMapLines = _wtoi(c_Name); // Load the boolean for map lines display into sfSettings data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfSettings->iColorScheme = _wtoi(c_Name); // Load the color scheme into sfSettings data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfSettings->bSmoothYesNo = _wtoi(c_Name); // Load the boolean for accel smoothing into sfSettings data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfSettings->bXAxis_KM = _wtoi(c_Name); // Load the Distance setting into sfSettings data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.bShowReferenceLap = _wtoi(c_Name); // Load the booelean to display Ref Lap into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.bSmoothYesNo = _wtoi(c_Name); // Load the boolean for accel smoothing into LapOpts data structuree + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.bTractionCircle = _wtoi(c_Name); // Load the boolean to display Traction Circle into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.bXAxis_KM = _wtoi(c_Name); // Load the Distance setting into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.eSortPreference = (LAPSORTSTYLE)_wtoi(c_Name); // Load the Lap Sort pref into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.eUnitPreference = (UNIT_PREFERENCE)_wtoi(c_Name); // Load the kph/mph/mps seeting into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.e_Orientation = (ORIENTATION)_wtoi(c_Name); // Load the Phone Orientation into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.fColorScheme = _wtoi(c_Name); // Load the Color Scheme into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.fDrawGuides = _wtoi(c_Name); // Load the Guidelines Drawing boolean into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.fDrawLines = _wtoi(c_Name); // Load the Lines/Dots Drawing boolean into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.fDrawSplitPoints = _wtoi(c_Name); // Load the Split Points boolean into LapOpts data structure } - } - -INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) - -{ -// Show Splash screen as first screen - CSplashDlg splash; - ArtShowDialog(&splash); - - if(strcmp(lpCmdLine,"unit") == 0) - { - return UnitTests(); - } - INITCOMMONCONTROLSEX initCtrls; - initCtrls.dwICC = ICC_LISTVIEW_CLASSES; - initCtrls.dwSize = sizeof(initCtrls); - - InitCommonControlsEx(&initCtrls); - - CMainUI sfUI; - g_pUI = &sfUI; - //CLapReceiver sfLaps(&sfUI); - - - CSQLiteLapDB sfLaps(&sfUI); - bool fDBOpened = false; - - int iRaceId[50] = {0}; - TCHAR szDBPath[MAX_PATH]; - if(ArtGetSaveFileName(NULL,L"Select .wflp to open or save to",szDBPath,NUMCHARS(szDBPath),L"WifiLapper Files (*.wflp)\0*.WFLP\0\0")) - { - const bool fFileIsNew = !DoesFileExist(szDBPath); - if(fFileIsNew) - { - // let's make sure there's a .wflp suffix on that bugger. - if(!str_ends_with(szDBPath,L".wflp")) - { - wcsncat(szDBPath,L".wflp", NUMCHARS(szDBPath)); - } - } - // they chose one to open, so open it. - if(sfLaps.Init(szDBPath)) - { - if(!fFileIsNew) - { - // show the race-selection dialog - RACESELECT_RESULT sfRaceResult; - CRaceSelectDlg sfRaceSelect(&sfLaps,&sfRaceResult); - ::ArtShowDialog(&sfRaceSelect); - if(!sfRaceResult.fCancelled) - { - for (int z = 0; z < 50; z++) - { - iRaceId[z] = sfRaceResult.iRaceId[z]; // Load the first selected race session - } - fDBOpened = true; - } - else - { - iRaceId[0] = -1; - fDBOpened = true; - } - } - else - { - iRaceId[0] = -1; - fDBOpened = true; - } - } - - } - else - { - return 0; - } - - if(!fDBOpened) - { - // they didn't choose a file, so just use a temp DB. - TCHAR szTempPath[MAX_PATH]; - GetTempPath(NUMCHARS(szTempPath),szTempPath); - wcscat(szTempPath,L"\\pitsidetemp.wflp"); - if(sfLaps.Init(szTempPath)) - { - // success! - wcscpy(szDBPath,szTempPath); - } - } - if(!fDBOpened) - { - // disaster. - MessageBox(NULL,L"Pitside was unable to create a database to save data to. Is your hard drive full?",L"Failed to create DB",MB_ICONERROR); - exit(0); - } - sfUI.SetRaceId(&iRaceId[0]); - - - g_pLapDB = &sfLaps; - - - LAPSUPPLIEROPTIONS x_sfLapOpts; //sfLapOpts contains all lap display options - InitPlotPrefs(x_sfLapOpts); // Initialize all PlotPrefs variables before displaying anything - - PITSIDE_SETTINGS sfSettings; + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.fElapsedTime = _wtoi(c_Name); // Load the Elapsed Time boolean into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.fIOIOHardcoded = _wtoi(c_Name); // Load the IOIO Hardcoded boolean into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.flWindowShiftX = _wtof(c_Name); // Load the Window ShiftX into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.flWindowShiftY = _wtof(c_Name); // Load the Window ShiftY into LapOpts data structure + } + + Line = lines[t++]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.iZoomLevels = _wtoi(c_Name); // Load the Zoom Level into LapOpts data structure + } + + int arraycounter = 0; // Now load the Plotting Preferences into the m_sfLapOpts.PlotPrefs array + for (int i = t; i < lines.size() && arraycounter < 50; i+=13) + { + Line = lines[i]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].iDataChannel = (DATA_CHANNEL)_wtoi(c_Name); // Load the data channel + } + + Line = lines[i+1]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + swprintf(sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].m_ChannelName, NUMCHARS(sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].m_ChannelName), c_Name); // Load the data channel + } + + Line = lines[i+2]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].iPlotView = _wtoi(c_Name); // Load current display mode for channel + } + + Line = lines[i+3]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].fMinValue = _wtof(c_Name); // Load the lower limit for channel + } + + Line = lines[i+4]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].fMaxValue = _wtof(c_Name); // Load the upper limit for channel + } + + Line = lines[i+5]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].iTransformYesNo = _wtoi(c_Name); // Load the transform flag for channel + } + + Line = lines[i+6]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].fTransAValue = _wtof(c_Name); // Load the A constant for channel + } + + Line = lines[i+7]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].fTransBValue = _wtof(c_Name); // Load the B constant for channel + } + + Line = lines[i+8]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_PlotPrefs[arraycounter].fTransCValue = _wtof(c_Name); // Load the C constant for channel + } + + Line = lines[i+9]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_SplitPoints[arraycounter].m_sfXPoint = _wtof(c_Name); // Load the split points + } + + Line = lines[i+10]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_SplitPoints[arraycounter].m_sfYPoint = _wtof(c_Name); // Load the split points + } + + Line = lines[i+11]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_SplitPoints[arraycounter].m_sfSectorTime = _wtoi(c_Name); // Load all sector times + } + + Line = lines[i+12]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.m_SplitPoints[arraycounter].m_sfSplitTime = _wtof(c_Name); // Load the lower limit for channel + } + arraycounter++; + } + t = t + (arraycounter) * 13; // Reset the line counter to collect the next set of data + + Line = lines[t]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); +// sfUI->m_sfLapOpts.fDrawSplitPoints = _wtoi(c_Name); // End of Data Channels + } + + t++; + Line = lines[t]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.fDrawSplitPoints = _wtoi(c_Name); // Load the setting to show split points + } + + t++; + Line = lines[t]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_sfLapOpts.LapId = _wtoi(c_Name); // Get the LapId for the reference lap + } + + t++; + Line = lines[t]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_eXChannel = (DATA_CHANNEL)_wtoi(c_Name); // Load the X-Axis data channel + } + t++; + + sfUI->m_lstYChannels.clear(); // Clear the current list of Data channels + for (t; t < lines.size(); t++ ) + { + Line = lines[t]; + { + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + sfUI->m_lstYChannels.push_back( (DATA_CHANNEL)_wtoi(c_Name) ); // Load the Y-Axis data channels + } + } + + in.close(); + } + return 1; +} + +// Converts ANSI strings to UNICODE strings +BOOL AnsiToUnicode( LPSTR pszAnsiString, LPWSTR pszwUniBuff, DWORD dwUniBuffSize ) +{ + int iRet = 0; + iRet = MultiByteToWideChar(CP_ACP, 0, pszAnsiString, -1, pszwUniBuff, dwUniBuffSize); + return ( 0 != iRet ); +} + +INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) + +{ + INITCOMMONCONTROLSEX initCtrls; + initCtrls.dwICC = ICC_LISTVIEW_CLASSES; + initCtrls.dwSize = sizeof(initCtrls); + LoadIcon(hInstance,_T("IDI_EXPLORERICON")); + InitCommonControlsEx(&initCtrls); + + CMainUI sfUI; + g_pUI = &sfUI; + //CLapReceiver sfLaps(&sfUI); + + CSQLiteLapDB sfLaps(&sfUI); + bool fDBOpened = false; + + int iRaceId[50] = {0}; + TCHAR szDBPath[MAX_PATH] = {NULL}; // Filename and path are contained in this string + TCHAR szTemp[512] = {NULL}; + TCHAR szLoadFileName[MAX_PATH] = {NULL}; + TCHAR wCmdLine[MAX_PATH] = {NULL}; + AnsiToUnicode(lpCmdLine, wCmdLine, sizeof(wCmdLine)); // Convert ANSI command line to UNICODE command + + PITSIDE_SETTINGS sfSettings; LoadPitsideSettings(&sfSettings); // Load preferences from "Settings.txt" file + LAPSUPPLIEROPTIONS x_sfLapOpts; //sfLapOpts contains all lap display options + InitPlotPrefs(x_sfLapOpts); // Initialize all PlotPrefs variables before displaying anything + sfUI.SetDisplayOptions(x_sfLapOpts); // Link x_sfLapOpts with CMainUI pointer + sfUI.SetRaceId(&iRaceId[0]); + x_sfLapOpts.LapId = 0; + + + if(strcmp(lpCmdLine,"unit") == 0) // Check for special test command line + { + return UnitTests(); + DWORD dwRet = MessageBox(NULL,wCmdLine,L"Unit", MB_APPLMODAL | MB_ICONWARNING | MB_OK | MB_TOPMOST | MB_DEFBUTTON2); + } + else if( str_ends_with( wCmdLine, L".wflp\"") ) // Check if user clicked on an associated WFLP file and load it + { + // First we must remove the quote marks from the beginning and end of the file name in the command line + int start = 1; + int end = NUMCHARS(wCmdLine); + for (int q=start; q lines; + ifstream in; + if ( DoesFileExist(szTempPath) ) // Make sure that the file exists before opening it + { + in.open(szTempPath); + // Read in the first line of the "LatestSettings.txt" file + // Store them in the 'lines' vector + string Line; + if(!in.eof() && !in.fail()) + { + getline(in, Line); + if (Line != "//") + { + lines.push_back(Line); + } + } + in.close(); + TCHAR szText[MAX_PATH]; + + // Now let's process the information and load it in the sfUI data structure + { + string Line = lines[0]; + TCHAR *c_Name = new TCHAR[Line.size()+1]; + c_Name[Line.size()] = 0; + copy(Line.begin(), Line.end(), c_Name); + swprintf(szText, NUMCHARS(szText), c_Name); // Load name of last-processed file in szDBPath + } + if ( _wcsnicmp( szText, szDBPath, NUMCHARS(szDBPath) ) == 0 ) // Opening the same file, so load see if user wants to return to previous session + { + int iRet = MessageBoxW(NULL,L"Do you want to pick up where you left off?",L"Database loaded previously",MB_ICONERROR | MB_YESNO); + if(iRet == IDYES) + { + LoadSettings(szDBPath, &sfSettings, &sfUI); // Let's overwrite the default preferences with the settings from the last instance run + for (int t=0; t<50; t++) + { + iRaceId[t]=sfUI.m_iRaceId[t]; + } + fDBOpened = true; + } + else + { + // show the race-selection dialog + RACESELECT_RESULT sfRaceResult; + CRaceSelectDlg sfRaceSelect(&sfLaps,&sfRaceResult); + ::ArtShowDialog(&sfRaceSelect); + if(!sfRaceResult.fCancelled) + { + for (int z = 0; z < 50; z++) + { + iRaceId[z] = sfRaceResult.iRaceId[z]; // Load the first selected race session + sfUI.m_iRaceId[z] = sfRaceResult.iRaceId[z]; // Load these RaceId's into the global pointer + } + fDBOpened = true; + } + else + { + iRaceId[0] = -1; + sfUI.m_iRaceId[0] = -1; + fDBOpened = true; + } + } + } + else + { + // show the race-selection dialog + RACESELECT_RESULT sfRaceResult; + CRaceSelectDlg sfRaceSelect(&sfLaps,&sfRaceResult); + ::ArtShowDialog(&sfRaceSelect); + if(!sfRaceResult.fCancelled) + { + for (int z = 0; z < 50; z++) + { + iRaceId[z] = sfRaceResult.iRaceId[z]; // Load the first selected race session + sfUI.m_iRaceId[z] = sfRaceResult.iRaceId[z]; // Load these RaceId's into the global pointer + } + fDBOpened = true; + } + else + { + iRaceId[0] = -1; + sfUI.m_iRaceId[0] = -1; + fDBOpened = true; + } + } + } + else + { + // show the race-selection dialog + RACESELECT_RESULT sfRaceResult; + CRaceSelectDlg sfRaceSelect(&sfLaps,&sfRaceResult); + ::ArtShowDialog(&sfRaceSelect); + if(!sfRaceResult.fCancelled) + { + for (int z = 0; z < 50; z++) + { + iRaceId[z] = sfRaceResult.iRaceId[z]; // Load the first selected race session + sfUI.m_iRaceId[z] = sfRaceResult.iRaceId[z]; // Load these RaceId's into the global pointer + } + fDBOpened = true; + } + else + { + iRaceId[0] = -1; + sfUI.m_iRaceId[0] = -1; + fDBOpened = true; + } + } + } + } + else + { + iRaceId[0] = -1; + sfUI.m_iRaceId[0] = -1; + fDBOpened = true; + } + } + + if(!fDBOpened) + { + // they didn't choose a file, so just use a temp DB. + TCHAR szTempPath[MAX_PATH]; + GetTempPath(NUMCHARS(szTempPath),szTempPath); + wcscat(szTempPath,L"pitsidetemp.wflp"); + if(sfLaps.Init(szTempPath)) + { + // success! + wcscpy(szDBPath,szTempPath); + iRaceId[0] = -1; + sfUI.m_iRaceId[0] = -1; + fDBOpened = true; + } + } + + if(!fDBOpened) + { + // disaster. + MessageBox(NULL,L"Pitside was unable to create a database to save data to. Is your hard drive full?",L"Failed to create DB",MB_ICONERROR); + exit(0); + } + g_pLapDB = &sfLaps; switch (sfSettings.iVelocity) { @@ -3043,48 +4654,71 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine x_sfLapOpts.fColorScheme = false; // Grey background as a default, true = black } } + switch (sfSettings.bSmoothYesNo) + { + case 0: + case 1: + { + x_sfLapOpts.bSmoothYesNo = sfSettings.bSmoothYesNo; // Assign smoothing setting from Settings.txt file + break; + } + } + switch (sfSettings.bXAxis_KM) + { + case 0: + case 1: + { + x_sfLapOpts.bXAxis_KM = sfSettings.bXAxis_KM; // Assign choice of LAT or KM for X-Axis setting from Settings.txt file + break; + } + } x_sfLapOpts.eSortPreference = SORTSTYLE_BYTIMEOFRACE; // Default sort Lap List by time of lap - sfUI.SetDisplayOptions(x_sfLapOpts); - sfUI.SetDBPath(szDBPath); - - PitsideHTTP aResponder(g_pLapDB,&sfUI); - if(sfSettings.fRunHTTP && sfSettings.iHTTPPort > 0 && sfSettings.iHTTPPort < 65536) - { - g_pHTTPServer = new SimpleHTTPServer(); - - bool fTryAgain = false; - do - { - fTryAgain = false; - if(!g_pHTTPServer->Init(sfSettings.iHTTPPort,&aResponder)) - { - TCHAR szMsg[200]; - _snwprintf(szMsg,NUMCHARS(szMsg),L"Pitside was unable to start the HTTP server on port %d. Do you want to open settings.txt to try another port or disable the server?",sfSettings.iHTTPPort); - int iRet = MessageBox(NULL,szMsg,L"Failed to start HTTP server",MB_ICONERROR | MB_YESNO); - if(iRet == IDYES) - { - TCHAR szPath[MAX_PATH]; - if(GetAppFolder(szPath,NUMCHARS(szPath))) - { - wcscat(szPath,L"settings.txt"); - _wsystem(szPath); - - LoadPitsideSettings(&sfSettings); - fTryAgain = sfSettings.fRunHTTP; - } - } - } - } - while(fTryAgain); - } - else - { - g_pHTTPServer = NULL; - } - - HANDLE hRecvThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ReceiveThreadProc, (LPVOID)&sfLaps, 0, NULL); - - ArtShowDialog(&sfUI); - exit(0); -} - + swprintf(sfUI.m_szPath, NUMCHARS(sfUI.m_szPath), szDBPath); // Load name of the chosen file into the sfUI pointer + + PitsideHTTP aResponder(g_pLapDB,&sfUI); + if(sfSettings.fRunHTTP && sfSettings.iHTTPPort > 0 && sfSettings.iHTTPPort < 65536) + { + g_pHTTPServer = new SimpleHTTPServer(); + + bool fTryAgain = false; + do + { + fTryAgain = false; + if(!g_pHTTPServer->Init(sfSettings.iHTTPPort,&aResponder)) + { + TCHAR szMsg[512]; + _snwprintf(szMsg,NUMCHARS(szMsg),L"Pitside was unable to start the HTTP server on port %d. Do you want to open settings.txt to try another port or disable the server?\n\nNOTE: This will also stop all communication from the phone to Pitside",sfSettings.iHTTPPort); + int iRet = MessageBox(NULL,szMsg,L"Failed to start HTTP server",MB_ICONERROR | MB_YESNO); + if(iRet == IDYES) + { + TCHAR szPath[MAX_PATH]; + if(GetAppFolder(szPath,NUMCHARS(szPath))) + { + wcscat(szPath,L"settings.txt"); + _wsystem(szPath); + + LoadPitsideSettings(&sfSettings); + fTryAgain = sfSettings.fRunHTTP; + } + } + } + } + while(fTryAgain); + } + else + { + g_pHTTPServer = NULL; + } + if(sfSettings.fRunHTTP) // Only try to receive phone information when the HTTP server is turned on + { + HANDLE hRecvThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ReceiveThreadProc, (LPVOID)&sfLaps, 0, NULL); + } + // Show the Open Dialog and start Pitside Console + ArtShowDialog(&sfUI); + + // Exiting the program. + SaveSettings(szDBPath, &sfSettings, &sfUI); // Let's save as many preferences and current settings as we can for next execution cycle before closing + + exit(0); // +} + diff --git a/PitsideConsole/PitsideConsole/PitsideConsole.cpp.rej b/PitsideConsole/PitsideConsole/PitsideConsole.cpp.rej new file mode 100644 index 0000000..21e8f23 --- /dev/null +++ b/PitsideConsole/PitsideConsole/PitsideConsole.cpp.rej @@ -0,0 +1,14 @@ +diff a/PitsideConsole/PitsideConsole/PitsideConsole.cpp b/PitsideConsole/PitsideConsole/PitsideConsole.cpp (rejected hunks) +@@ -2114,8 +1956,11 @@ LPDEVMODE GetLandscapeDevMode(HWND hWnd, wchar_t *pDevice, HANDLE hPrinter) + const static DWORD UPDATE_VALUES = 0x10; + const static DWORD UPDATE_TRACTIONCIRCLE = 0x20; + const static DWORD UPDATE_ALLDATA = 0x40; ++ const static DWORD UPDATE_ALL = 0xFFFF; ++ ++ const static DWORD UPDATE_ADD2LIST = 0x10000; ++ + +- const static DWORD UPDATE_ALL = 0xffffffff; + // Pull in PlotPrefs array as well as lines vs. dots and Painting color scheme settings from Settings.txt file + void SetDisplayOptions(const LAPSUPPLIEROPTIONS& lapOpts) + { diff --git a/PitsideConsole/PitsideConsole/PitsideConsole.rc b/PitsideConsole/PitsideConsole/PitsideConsole.rc index e37a2da..01a7a3e 100644 --- a/PitsideConsole/PitsideConsole/PitsideConsole.rc +++ b/PitsideConsole/PitsideConsole/PitsideConsole.rc @@ -1,224 +1,215 @@ -#include "Resource.h" -#include -#include "commctrl.h" - -IDI_EXPLORERICON ICON "res\\pitside.ico" -IDB_SPLASHIMAGE BITMAP "res\\splash.bmp" - -IDD_DLGFIRST DIALOG 100, 100, 745, 350 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX -CAPTION "Pitside" -FONT 8, "MS Shell Dlg" -MENU IDM_OPTIONS -BEGIN - CONTROL "", IDC_LAPS, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SHOWSELALWAYS, 0,150,150,200 - LTEXT "",IDC_DISPLAY,155,63,590,282 -// LTEXT "",IDC_SUBDISPLAY,520,0,150,63 - LTEXT "",IDC_SUBDISPLAY,520,0,87,63 - LTEXT "",IDC_TRACTIONCIRCLEMAP,610,0,63,63 - AUTORADIOBUTTON "Map",IDC_DISPLAYTYPE_LINE,155,0,30,12 - AUTORADIOBUTTON "Data Plot",IDC_DISPLAYTYPE_PLOT,185,0,45,12 - //AUTORADIOBUTTON "Reception",IDC_DISPLAYTYPE_RECEPTION,230,0,50,12 - CONTROL "", IDC_XAXIS, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS, 0,0,75,150 - CONTROL "", IDC_YAXIS, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SHOWSELALWAYS, 75,0,75,150 - - EDITTEXT IDC_COMMENTTEXT, 155,12,93,12 - PUSHBUTTON "Set Comment", IDC_SETDRIVER, 250,0,75,12 - PUSHBUTTON "Use as reference lap", IDC_SETREFERENCE, 250,14,75,12 - PUSHBUTTON "Clear Selection", IDC_CLEARSELECTION, 250,28,75,12 - PUSHBUTTON "Send Message", IDC_SENDMESSAGE, 250,42,75,12 - - LTEXT "", IDC_CURRENTREFERENCE, 155,26,93,24 - LTEXT "", IDC_MESSAGESTATUS, 155,43,93,24 - LTEXT "Phone: ", IDC_CURRENTREMOTEIP, 155,55,100,10 - LTEXT "Current Lap: ", IDC_LIVELAPTIME, 255,55,100,10 - LTEXT "1: ", IDC_VALUE_CHANNEL1, 328,0,190,12 - LTEXT "2: ", IDC_VALUE_CHANNEL2, 328,12,190,12 - LTEXT "3: ", IDC_VALUE_CHANNEL3, 328,24,190,12 - LTEXT "4: ", IDC_VALUE_CHANNEL4, 328,36,190,12 - LTEXT "5: ", IDC_VALUE_CHANNEL5, 328,48,190,12 -END - -// Dialog box showing the splash screen -IDD_DLGSPLASH DIALOG 100,100,200,250 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Welcome to Pitside" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "",IDC_SPLASHIMAGE,"Static",SS_BITMAP,0,0,200,200 - CTEXT "https://sites.google.com/site/wifilapper",IDC_LBLMESSAGE6,0,200,200,20 - PUSHBUTTON "OK", IDOK, 0,220,200,30 -END - -// Dialog box for sending messages to the car -IDD_DLGMESSAGE DIALOG 280, 200, 200, 85 -STYLE DS_MODALFRAME | WS_EX_TOPMOST | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Pit->Car Message" -FONT 8, "MS Shell Dlg" -BEGIN - LTEXT "Message",IDC_LBLMESSAGE,5,5,100,12 - EDITTEXT IDC_EDTMESSAGE,105,5,100,12 - LTEXT "Time to display, min (Max=3)",IDC_LBLTIME,5,19,100,12 - EDITTEXT IDC_EDTTIME,105,19,100,12 - LTEXT "Send attempt time, min (Max=3)",IDC_LBLATTEMPTTIME,5,33,100,12 - EDITTEXT IDC_EDTATTEMPTTIME,105,33,100,12 - LTEXT "Pitside may hang for up to 60s on next message send\nif previous attempt failed or was aborted",IDC_LBLMESSAGE2,5,47,195,24 - PUSHBUTTON "OK", IDOK, 5,67,95,18 - PUSHBUTTON "Cancel", IDCANCEL, 100,67,95,18 -END - -// Dialog box for showing the Traction Circle display -IDD_TRACTIONCIRCLE DIALOG 485,0,63,63 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | WS_POPUP | WS_THICKFRAME // | WS_SIZEBOX //| WS_SYSMENU -CAPTION "" -FONT 10, "MS Shell Dlg" -BEGIN - LTEXT "",IDC_TRACTIONCIRCLEMAP2,0,0,63,63 -END - -// Dialog box for setting sector split points -IDD_SETSPLITPOINTS DIALOG 50, 50, 400, 300 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_TABSTOP -CAPTION "Set Sector Split Points" -FONT 10, "MS Shell Dlg" -BEGIN - CTEXT "Left-Click on the map, then choose your split point\n(Clear All to end sector displaying)",IDC_LBLSPLIT1,5,5,390,25 - PUSHBUTTON "Set Split 1", IDC_SETSPLIT1, 5,30,50,20 - PUSHBUTTON "Set Split 2", IDC_SETSPLIT2, 5,55,50,20 - PUSHBUTTON "Set Split 3", IDC_SETSPLIT3, 5,80,50,20 - PUSHBUTTON "Set Split 4", IDC_SETSPLIT4, 5,105,50,20 - PUSHBUTTON "Set Split 5", IDC_SETSPLIT5, 5,130,50,20 - PUSHBUTTON "Set Split 6", IDC_SETSPLIT6, 5,155,50,20 - PUSHBUTTON "Set Split 7", IDC_SETSPLIT7, 5,180,50,20 - PUSHBUTTON "Set Split 8", IDC_SETSPLIT8, 5,205,50,20 - PUSHBUTTON "Clear All", IDRESET, 5,250,50,20 - LTEXT "",IDC_LBLSPLITMAP,60,27,335,250 - PUSHBUTTON "OK", IDOK, 5,280,195,20 - PUSHBUTTON "Cancel", IDCANCEL, 200,280,195,20 -END - -// Dialog box for displaying sector split times -IDD_SHOWSECTORS DIALOG 250, 75, 375, 99 -STYLE DS_MODALFRAME | WS_EX_TOPMOST | WS_POPUP | WS_CAPTION -CAPTION "Sector Times" -FONT 9, "MS Shell Dlg" -BEGIN - LTEXT "\t\tLap ID\t\t\tSect 1\tSect 2\tSect 3\tSect 4\tSect 5\tSect 6\tSect 7\tSect 8\tSect 9", IDC_SHOW_SECTORS,5,0,370,12 - LTEXT "Lap 1", IDC_SHOW_LAP0, 5,15,375,12 - LTEXT "Lap 2", IDC_SHOW_LAP1, 5,27,375,12 - LTEXT "Lap 3", IDC_SHOW_LAP2, 5,39,375,12 - LTEXT "Lap 4", IDC_SHOW_LAP3, 5,51,375,12 - LTEXT "Lap 5", IDC_SHOW_LAP4, 5,63,375,12 - LTEXT "Lap 6", IDC_SHOW_LAP5, 5,75,375,12 - LTEXT "Lap 7", IDC_SHOW_LAP6, 5,87,375,12 -END - -// dialog for selecting which race in a DB we want to use -IDD_SELECTRACE DIALOG 150, 200, 200, 200 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Select race to load" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "", IDC_RACE, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT/* | LVS_SINGLESEL*/ | LVS_SHOWSELALWAYS, 0,0,200,180 - PUSHBUTTON "OK", IDOK, 5,180,95,20 - PUSHBUTTON "Cancel", IDCANCEL, 100,180,95,20 -END - -// dialog for selecting which race sessions in DB we want to use for T&S -IDD_SELECTSESSIONS DIALOG 150, 200, 200, 200 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Select T&S Race Sessions (MAX = 50)" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "", IDC_RACE, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SHOWSELALWAYS, 0,0,200,180 - PUSHBUTTON "OK", IDOK, 5,180,95,20 - PUSHBUTTON "Cancel", IDCANCEL, 100,180,95,20 -END - -// dialog for displaying T&S data results -IDD_TIMINGSCORING DIALOG 150, 200, 500, 390 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX -CAPTION "Best Laps & Race Standings from Selected Sessions" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "", IDC_TIMINGSCORING, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS, 5,0,298,370 - CTEXT "****RACE STANDINGS****", IDC_RACE_TITLE, 308,10,187,12 - CTEXT "", IDC_RACE_PROGRESS, 308,25,187,12 - CONTROL "", IDC_RACESCORING, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS, 308,40,187,240 - PUSHBUTTON "Save Results", IDC_RACE_SAVE, 313,285,85,15 - PUSHBUTTON "Re-Run Race Scenario", IDC_RACE_RERUN, 400,285,85,15 - CTEXT "Enter race information below", IDC_RACE_INFO, 308,305,187,12 +#include "Resource.h" +#include +#include "commctrl.h" + +"IDI_EXPLORERICON" ICON "res\\pitside.ico" +IDB_SPLASHIMAGE BITMAP "res\\splash.bmp" + +IDD_DLGFIRST DIALOG 100, 100, 745, 350 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX +CAPTION "Pitside" +FONT 8, "MS Shell Dlg" +MENU IDM_OPTIONS +BEGIN + + CONTROL "", IDC_LAPS, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SHOWSELALWAYS, 0,150,150,200 + LTEXT "",IDC_DISPLAY,155,63,590,282 + LTEXT "",IDC_TRACTIONCIRCLEMAP,520,0,63,63 + LTEXT "",IDC_SUBDISPLAY,586,0,87,63 + AUTORADIOBUTTON "Map",IDC_DISPLAYTYPE_LINE,155,0,30,12 + AUTORADIOBUTTON "Data Plot",IDC_DISPLAYTYPE_PLOT,185,0,45,12 + //AUTORADIOBUTTON "Reception",IDC_DISPLAYTYPE_RECEPTION,230,0,50,12 + CONTROL "", IDC_XAXIS, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS, 0,0,75,150 + CONTROL "", IDC_YAXIS, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SHOWSELALWAYS, 75,0,75,150 + + EDITTEXT IDC_COMMENTTEXT, 155,12,81,12 + PUSHBUTTON "Set Comment", IDC_SETDRIVER, 250,0,75,12 + PUSHBUTTON "X", IDC_CLEARCOMMENT, 237,13,10,10 + PUSHBUTTON "Use as reference lap", IDC_SETREFERENCE, 250,14,75,12 + PUSHBUTTON "Send Message", IDC_SENDMESSAGE, 250,28,75,12 + PUSHBUTTON "Live Data", IDC_LIVEDATA, 250,42,75,12 + LTEXT "Current Lap: ", IDC_LIVELAPTIME, 255,56,70,10 + + LTEXT "", IDC_CURRENTREFERENCE, 155,26,93,24 + LTEXT "", IDC_MESSAGESTATUS, 155,43,93,24 + LTEXT "Phone: ", IDC_CURRENTREMOTEIP, 155,55,100,10 + CONTROL "", IDC_DATAVALUES, WC_LISTVIEW, WS_TABSTOP | LVS_REPORT | LVS_SHOWSELALWAYS, 328,0,190,60 +END +/* +// Window for sub-display to appear in +IDD_DLGSUBDISPLAY DIALOG 586,0,87,63 +STYLE DS_MODALFRAME | WS_EX_TOPMOST | DS_SETFONT | WS_CHILD | WS_POPUP | WS_THICKFRAME +CAPTION "Map Display" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "",IDC_SUBDISPLAY,5,5,77,53 + +END +*/ +// Dialog box for sending messages to the car +IDD_DLGMESSAGE DIALOG 280, 200, 200, 85 +STYLE DS_MODALFRAME | WS_EX_TOPMOST | DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Pit->Car Message" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Message",IDC_LBLMESSAGE,5,5,100,12 + EDITTEXT IDC_EDTMESSAGE,105,5,100,12 + LTEXT "Time to display, min (Max=3)",IDC_LBLTIME,5,19,100,12 + EDITTEXT IDC_EDTTIME,105,19,100,12 + LTEXT "Send attempt time, min (Max=3)",IDC_LBLATTEMPTTIME,5,33,100,12 + EDITTEXT IDC_EDTATTEMPTTIME,105,33,100,12 + LTEXT "Pitside may hang for up to 60s on next message send\nif previous attempt failed or was aborted",IDC_LBLMESSAGE2,5,47,195,24 + PUSHBUTTON "OK", IDOK, 5,67,95,18 + PUSHBUTTON "Cancel", IDCANCEL, 100,67,95,18 +END + +// Dialog box for setting sector split points +IDD_SETSPLITPOINTS DIALOG 50, 50, 400, 300 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_TABSTOP +CAPTION "Set Sector Split Points" +FONT 10, "MS Shell Dlg" +BEGIN + CTEXT "Left-Click on the map, then choose your split point\n(Clear All to end sector displaying)",IDC_LBLSPLIT1,5,5,390,25 + PUSHBUTTON "Set Split 1", IDC_SETSPLIT1, 5,30,50,20 + PUSHBUTTON "Set Split 2", IDC_SETSPLIT2, 5,55,50,20 + PUSHBUTTON "Set Split 3", IDC_SETSPLIT3, 5,80,50,20 + PUSHBUTTON "Set Split 4", IDC_SETSPLIT4, 5,105,50,20 + PUSHBUTTON "Set Split 5", IDC_SETSPLIT5, 5,130,50,20 + PUSHBUTTON "Set Split 6", IDC_SETSPLIT6, 5,155,50,20 + PUSHBUTTON "Set Split 7", IDC_SETSPLIT7, 5,180,50,20 + PUSHBUTTON "Set Split 8", IDC_SETSPLIT8, 5,205,50,20 + PUSHBUTTON "Clear All", IDRESET, 5,250,50,20 + LTEXT "",IDC_LBLSPLITMAP,60,27,335,250 + PUSHBUTTON "OK", IDOK, 5,280,195,20 + PUSHBUTTON "Cancel", IDCANCEL, 200,280,195,20 +END + +// Dialog box for displaying all data for a given point +IDD_ALLDATADISPLAY DIALOG 250, 75, 400, 250 +STYLE DS_MODALFRAME | WS_EX_TOPMOST | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Data Point Information" +FONT 10, "MS Shell Dlg" +BEGIN + CTEXT "****Data Details****", IDC_RACE_TITLE, 5,5,365,12 + CONTROL "", IDC_ALLDATADISPLAY, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS, 5,20,390,225 +END + +// Dialog box for displaying sector split times +IDD_SHOWSECTORS DIALOG 250, 75, 380, 99 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION +CAPTION "Sector Times" +FONT 9, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_SHOW_SECTORS, WC_LISTVIEW, WS_TABSTOP | LVS_REPORT | LVS_SHOWSELALWAYS, 0,0,380,99 +END + +// dialog for selecting which race in a DB we want to use +IDD_SELECTRACE DIALOG 150, 200, 200, 200 +STYLE DS_MODALFRAME | WS_POPUP | DS_SETFONT | WS_CAPTION | WS_SYSMENU +CAPTION "Select one or more race sessions to load" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_RACE, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT/* | LVS_SINGLESEL*/ | LVS_SHOWSELALWAYS, 0,0,200,180 + PUSHBUTTON "OK", IDOK, 5,180,95,20 + PUSHBUTTON "Cancel", IDCANCEL, 100,180,95,20 +END + +// dialog for selecting which race sessions in DB we want to use for T&S +IDD_SELECTSESSIONS DIALOG 150, 200, 200, 200 +STYLE DS_MODALFRAME | WS_POPUP | DS_SETFONT | WS_CAPTION | WS_SYSMENU +CAPTION "Select T&S Race Sessions (MAX = 50)" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_RACE, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SHOWSELALWAYS, 0,0,200,180 + PUSHBUTTON "OK", IDOK, 5,180,95,20 + PUSHBUTTON "Cancel", IDCANCEL, 100,180,95,20 +END + +// dialog for displaying T&S data results +IDD_TIMINGSCORING DIALOG 150, 200, 500, 390 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU | WS_MINIMIZEBOX +CAPTION "Best Laps & Race Standings from Selected Sessions" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_TIMINGSCORING, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS, 5,0,298,370 + CTEXT "****RACE STANDINGS****", IDC_RACE_TITLE, 308,10,187,12 + CTEXT "", IDC_RACE_PROGRESS, 308,25,187,12 + CONTROL "", IDC_RACESCORING, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS, 308,40,187,240 + PUSHBUTTON "Save Results", IDC_RACE_SAVE, 313,285,85,15 + PUSHBUTTON "Re-Run Race Scenario", IDC_RACE_RERUN, 400,285,85,15 + CTEXT "Enter race information below", IDC_RACE_INFO, 308,305,187,12 EDITTEXT IDC_RACE_COMMENT,308,318,187,12 - PUSHBUTTON "Start Race", IDSTARTRACE, 313,335,177,20 - PUSHBUTTON "End Race", IDENDRACE, 313,360,177,20 - PUSHBUTTON "Refresh", IDRESCAN, 5,370,149,20 - PUSHBUTTON "Close", IDCANCEL, 154,370,149,20 -END - -// dialog for choosing Start/End times for T&S -IDD_RACE_RERUN DIALOG 250, 250, 200, 120 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Enter Time Markers" -FONT 8, "MS Shell Dlg" -BEGIN - CTEXT "Enter START marker from .txt file", IDC_RACE_START_TEXT, 5,5,190,12 + PUSHBUTTON "Start Race", IDSTARTRACE, 313,335,177,20 + PUSHBUTTON "End Race", IDENDRACE, 313,360,177,20 + PUSHBUTTON "Refresh", IDRESCAN, 5,370,149,20 + PUSHBUTTON "Close", IDCANCEL, 154,370,149,20 +END + +// dialog for choosing Start/End times for T&S +IDD_RACE_RERUN DIALOG 250, 250, 200, 120 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU +CAPTION "Enter Time Markers" +FONT 8, "MS Shell Dlg" +BEGIN + CTEXT "Enter START marker from .txt file", IDC_RACE_START_TEXT, 5,5,190,12 EDITTEXT IDC_RACE_START,5,25,190,12 - CTEXT "Enter END marker from .txt file", IDC_RACE_END_TEXT, 5,60,190,12 + CTEXT "Enter END marker from .txt file", IDC_RACE_END_TEXT, 5,60,190,12 EDITTEXT IDC_RACE_END,5,80,190,12 - PUSHBUTTON "OK", IDOK, 5,100,95,20 - PUSHBUTTON "Cancel", IDCANCEL, 100,100,95,20 -END - -// dialog for selecting which race in a DB we want to edit -IDD_SELECTRACEEDIT DIALOG 150, 200, 200, 213 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Select race(s) to edit" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "", IDC_RACE, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SHOWSELALWAYS, 0,0,200,180 - PUSHBUTTON "Rename", IDC_RACEEDIT_RENAME, 5,180,95,12 - PUSHBUTTON "Merge", IDC_RACEEDIT_MERGE, 100,180,95,12 - PUSHBUTTON "OK", IDOK, 5,193,95,20 - PUSHBUTTON "Cancel", IDCANCEL, 100,193,95,20 -END - -// confirm dialog for editing races in a DB -IDD_RACEEDITCONFIRM DIALOG 350, 200, 250, 125 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "**WARNING**" -FONT 8, "MS Shell Dlg" -BEGIN - LTEXT "Are you sure you want to merge these race sessions?\n\nONLY merge race sessions that are on the same track!\n\nEven then, Start/Finish differences will disrupt graphs such as Time Slip.\n\n\nTHIS OPERATION CANNOT BE UNDONE",IDC_LBLMESSAGE3,5,5,245,90 - PUSHBUTTON "Merge", IDOK, 5,100,120,24 - PUSHBUTTON "Cancel", IDCANCEL, 125,100,120,24 -END - -// About... dialog with hyperlink now -IDD_ABOUT DIALOG 350, 200, 250, 125 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About Pitside Console" -FONT 8, "MS Shell Dlg" -BEGIN - CTEXT "Piside Console for Wifilapper\n\nVersion 2.003.0029\n\nThis is an Open Source project. If you want to contribute\n\n",IDC_LBLMESSAGE5,5,5,245,40 - CTEXT "https://sites.google.com/site/wifilapper",IDC_LBLMESSAGE6,5,60,245,20 - PUSHBUTTON "OK", IDOK, 5,100,240,24 -END - -// name input dialog for renaming races in a DB -IDD_RACENAMECHANGE DIALOG 350, 200, 200, 85 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Enter New Race Session Name" -FONT 8, "MS Shell Dlg" -BEGIN - LTEXT "Race Session(s) name?",IDC_LBLMESSAGE4,5,5,100,12 - EDITTEXT IDC_EDTMESSAGE2,5,25,190,12 - PUSHBUTTON "Rename", IDOK, 5,67,95,18 - PUSHBUTTON "Cancel", IDCANCEL, 100,67,95,18 -END - + PUSHBUTTON "OK", IDOK, 5,100,95,20 + PUSHBUTTON "Cancel", IDCANCEL, 100,100,95,20 +END + +// dialog for selecting which race in a DB we want to edit +IDD_SELECTRACEEDIT DIALOG 150, 200, 200, 213 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU +CAPTION "Select race(s) to edit" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_RACE, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_REPORT | LVS_SHOWSELALWAYS, 0,0,200,180 + PUSHBUTTON "Rename", IDC_RACEEDIT_RENAME, 5,180,95,12 + PUSHBUTTON "Merge", IDC_RACEEDIT_MERGE, 100,180,95,12 + PUSHBUTTON "OK", IDOK, 5,193,95,20 + PUSHBUTTON "Cancel", IDCANCEL, 100,193,95,20 +END + +// confirm dialog for editing races in a DB +IDD_RACEEDITCONFIRM DIALOG 350, 200, 250, 125 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU +CAPTION "**WARNING**" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Are you sure you want to merge these race sessions?\n\nONLY merge race sessions that are on the same track!\n\nEven then, Start/Finish differences will disrupt graphs such as Time Slip.\n\n\nTHIS OPERATION CANNOT BE UNDONE",IDC_LBLMESSAGE3,5,5,245,90 + PUSHBUTTON "Merge", IDOK, 5,100,120,24 + PUSHBUTTON "Cancel", IDCANCEL, 125,100,120,24 +END + +// About... dialog with hyperlink now +IDD_ABOUT DIALOG 300, 125, 250, 325 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU | WS_THICKFRAME +CAPTION "About Pitside Console" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDC_SPLASHIMAGE,"Static",SS_BITMAP,25,10,200,200 + CTEXT "Pitside Console for SpeedFreq/Wifilapper\n\nVersion 2.004.0019\n\nThis is an Open Source project. If you want to contribute\n\n",IDC_LBLMESSAGE5,5,230,245,40 + CTEXT "http://sites.google.com/site/speedfreqapp",IDC_LBLMESSAGE6,5,270,245,20 + PUSHBUTTON "OK", IDOK, 5,290,240,30 +END + +// name input dialog for renaming races in a DB +IDD_RACENAMECHANGE DIALOG 350, 200, 200, 85 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU +CAPTION "Enter New Race Session Name" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Race Session(s) name?",IDC_LBLMESSAGE4,5,5,100,12 + EDITTEXT IDC_EDTMESSAGE2,5,25,190,12 + PUSHBUTTON "Rename", IDOK, 5,67,95,18 + PUSHBUTTON "Cancel", IDCANCEL, 100,67,95,18 +END + // dialog for selecting plotting preferences IDD_PLOTPREFS DIALOG 250, 120, 524, 312 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX CAPTION "Choose plotting preferences" FONT 8, "MS Shell Dlg" BEGIN @@ -232,7 +223,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A1,305,32,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B1,342,32,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C1,379,32,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD1, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,32,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD1, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,32,100,200 LTEXT " 2: ", IDC_PLOTTYPE_CHANNEL2,5,44,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH2,105,44,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE2,150,44,45,12 @@ -242,7 +233,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A2,305,44,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B2,342,44,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C2,379,44,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD2, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,44,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD2, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,44,100,200 LTEXT " 3: ", IDC_PLOTTYPE_CHANNEL3,5,56,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH3,105,56,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE3,150,56,45,12 @@ -252,7 +243,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A3,305,56,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B3,342,56,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C3,379,56,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD3, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,56,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD3, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,56,100,200 LTEXT " 4: ", IDC_PLOTTYPE_CHANNEL4,5,68,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH4,105,68,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE4,150,68,45,12 @@ -262,7 +253,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A4,305,68,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B4,342,68,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C4,379,68,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD4, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,68,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD4, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,68,100,200 LTEXT " 5: ", IDC_PLOTTYPE_CHANNEL5,5,80,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH5,105,80,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE5,150,80,45,12 @@ -272,7 +263,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A5,305,80,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B5,342,80,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C5,379,80,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD5, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,80,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD5, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,80,100,200 LTEXT " 6: ", IDC_PLOTTYPE_CHANNEL6,5,92,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH6,105,92,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE6,150,92,45,12 @@ -282,7 +273,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A6,305,92,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B6,342,92,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C6,379,92,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD6, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,92,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD6, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,92,100,200 LTEXT " 7: ", IDC_PLOTTYPE_CHANNEL7,5,104,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH7,105,104,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE7,150,104,45,12 @@ -292,7 +283,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A7,305,104,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B7,342,104,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C7,379,104,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD7, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,104,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD7, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,104,100,200 LTEXT " 8: ", IDC_PLOTTYPE_CHANNEL8,5,116,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH8,105,116,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE8,150,116,45,12 @@ -302,7 +293,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A8,305,116,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B8,342,116,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C8,379,116,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD8, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,116,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD8, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,116,100,200 LTEXT " 9: ", IDC_PLOTTYPE_CHANNEL9,5,128,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH9,105,128,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE9,150,128,45,12 @@ -312,7 +303,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A9,305,128,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B9,342,128,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C9,379,128,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD9, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,128,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD9, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,128,100,200 LTEXT "10: ", IDC_PLOTTYPE_CHANNEL10,5,140,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH10,105,140,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE10,150,140,45,12 @@ -322,7 +313,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A10,305,140,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B10,342,140,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C10,379,140,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD10, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,140,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD10, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,140,100,200 LTEXT "11: ", IDC_PLOTTYPE_CHANNEL11,5,152,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH11,105,152,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE11,150,152,45,12 @@ -332,7 +323,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A11,305,152,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B11,342,152,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C11,379,152,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD11, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,152,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD11, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,152,100,200 LTEXT "12: ", IDC_PLOTTYPE_CHANNEL12,5,164,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH12,105,164,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE12,150,164,45,12 @@ -342,7 +333,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A12,305,164,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B12,342,164,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C12,379,164,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD12, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,164,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD12, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,164,100,200 LTEXT "13: ", IDC_PLOTTYPE_CHANNEL13,5,176,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH13,105,176,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE13,150,176,45,12 @@ -352,7 +343,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A13,305,176,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B13,342,176,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C13,379,176,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD13, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,176,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD13, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,176,100,200 LTEXT "14: ", IDC_PLOTTYPE_CHANNEL14,5,188,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH14,105,188,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE14,150,188,45,12 @@ -362,7 +353,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A14,305,188,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B14,342,188,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C14,379,188,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD14, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,188,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD14, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,188,100,200 LTEXT "15: ", IDC_PLOTTYPE_CHANNEL15,5,200,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH15,105,200,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE15,150,200,45,12 @@ -372,7 +363,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A15,305,200,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B15,342,200,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C15,379,200,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD15, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,200,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD15, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,200,100,200 LTEXT "16: ", IDC_PLOTTYPE_CHANNEL16,5,212,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH16,105,212,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE16,150,212,45,12 @@ -382,7 +373,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A16,305,212,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B16,342,212,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C16,379,212,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD16, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,212,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD16, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,212,100,200 LTEXT "17: ", IDC_PLOTTYPE_CHANNEL17,5,224,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH17,105,224,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE17,150,224,45,12 @@ -392,7 +383,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A17,305,224,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B17,342,224,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C17,379,224,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD17, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,224,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD17, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,224,100,200 LTEXT "18: ", IDC_PLOTTYPE_CHANNEL18,5,236,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH18,105,236,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE18,150,236,45,12 @@ -402,7 +393,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A18,305,236,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B18,342,236,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C18,379,236,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD18, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,236,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD18, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,236,100,200 LTEXT "19: ", IDC_PLOTTYPE_CHANNEL19,5,248,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH19,105,248,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE19,150,248,45,12 @@ -412,7 +403,7 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A19,305,248,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B19,342,248,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C19,379,248,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD19, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,248,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD19, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,248,100,200 LTEXT "20: ", IDC_PLOTTYPE_CHANNEL20,5,260,100,12 AUTORADIOBUTTON "Graph",IDC_PLOTTYPE_GRAPH20,105,260,45,12 AUTORADIOBUTTON "Value",IDC_PLOTTYPE_VALUE20,150,260,45,12 @@ -422,81 +413,91 @@ BEGIN EDITTEXT IDC_PLOTTYPE_TRANS_A20,305,260,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_B20,342,260,32,12 EDITTEXT IDC_PLOTTYPE_TRANS_C20,379,260,32,12 - CONTROL "", IDC_PLOTTYPE_LOAD20, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,260,100,200 + CONTROL "", IDC_PLOTTYPE_LOAD20, WC_COMBOBOX, CBS_DROPDOWNLIST |CBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE, 415,260,100,200 PUSHBUTTON "Rescan/Reset", IDC_PLOTTYPE_RESCAN, 122,275,180,12 PUSHBUTTON "OK", IDOK, 5,290,207,22 PUSHBUTTON "Cancel", IDCANCEL, 212,290,207,22 END - - -IDD_PROGRESS DIALOG 250, 150, 200, 50 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION -CAPTION "Working..." -FONT 8, "MS Shell Dlg" -BEGIN -END - -IDD_WARNING DIALOG 300, 250, 250, 150 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "*****WARNING*****" -FONT 8, "MS Shell Dlg" -BEGIN - CTEXT "",IDC_WARNING1,5,5,245,100 - PUSHBUTTON "OK", IDOK, 5,100,240,50 -END - + + +IDD_PROGRESS DIALOG 250, 150, 200, 50 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT +CAPTION "Working..." +FONT 8, "MS Shell Dlg" +BEGIN +END + +IDD_WARNING DIALOG 300, 250, 250, 150 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_SETFONT | WS_SYSMENU +CAPTION "*****WARNING*****" +FONT 8, "MS Shell Dlg" +BEGIN + CTEXT "",IDC_WARNING1,5,5,245,100 + PUSHBUTTON "OK", IDOK, 5,100,240,50 +END + //hMenu MENU DISCARDABLE -IDM_OPTIONS MENU +IDM_OPTIONS MENU BEGIN -POPUP "&File" - BEGIN +POPUP "&File" + BEGIN + MENUITEM "Open .wflp DB", ID_DATA_OPENDB + MENUITEM "Switch Race Session", ID_DATA_SWITCHSESSION + MENUITEM "Edit/Merge Race Sessions", ID_DATA_EDITSESSION + MENUITEM SEPARATOR + MENUITEM "Print...", IDM_PRINT_BM + MENUITEM SEPARATOR + MENUITEM "Export selected laps to CSV format", ID_DATA_DASHWARE + MENUITEM SEPARATOR + MENUITEM "Exit", ID_FILE_EXIT + END +POPUP "&Edit" + BEGIN + MENUITEM "Copy", ID_EDIT_COPY MENUITEM "Save Image", IDM_SAVE_BM - MENUITEM "Print...", IDM_PRINT_BM - MENUITEM "Exit", ID_FILE_EXIT - END -POPUP "&Edit" - BEGIN - MENUITEM "Copy", ID_EDIT_COPY - END -POPUP "&Options" - BEGIN - MENUITEM "Km/h", ID_OPTIONS_KMH - MENUITEM "MPH", ID_OPTIONS_MPH - MENUITEM "m/s", ID_OPTIONS_MS - MENUITEM SEPARATOR - MENUITEM "Set Split Points", ID_OPTIONS_SETSPLITS - MENUITEM SEPARATOR - MENUITEM "Show Traction Circle", ID_OPTIONS_TRACTIONCIRCLE - MENUITEM SEPARATOR - MENUITEM "Show all-time bests",ID_OPTIONS_SHOWBESTS - MENUITEM "Show driver bests",ID_OPTIONS_SHOWDRIVERBESTS - MENUITEM "Show Reference Lap",ID_OPTIONS_SHOWREFERENCELAP - MENUITEM SEPARATOR - MENUITEM "Draw lines between data points",ID_OPTIONS_DRAWLINES - MENUITEM "Use dark background for plots",ID_OPTIONS_BACKGROUND - MENUITEM SEPARATOR - MENUITEM "Force plotted data to fixed scales",ID_OPTIONS_IOIO5VSCALE + END +POPUP "&Graphing" + BEGIN + MENUITEM "Km/h", ID_OPTIONS_KMH + MENUITEM "MPH", ID_OPTIONS_MPH + MENUITEM "m/s", ID_OPTIONS_MS + MENUITEM SEPARATOR + MENUITEM "X-Axis in KM", ID_OPTIONS_XAXIS_KM + MENUITEM "X-Axis in LAT", ID_OPTIONS_XAXIS_LAT + MENUITEM SEPARATOR + MENUITEM "Set Split Points", ID_OPTIONS_SETSPLITS + MENUITEM "Cancel Split Points", ID_OPTIONS_CANCELSPLITS + MENUITEM SEPARATOR + MENUITEM "Transient Traction Circle", ID_OPTIONS_TRACTIONCIRCLE + MENUITEM SEPARATOR + MENUITEM "Show all-time bests",ID_OPTIONS_SHOWBESTS + MENUITEM "Show driver bests",ID_OPTIONS_SHOWDRIVERBESTS + MENUITEM "Show Reference Lap",ID_OPTIONS_SHOWREFERENCELAP + MENUITEM SEPARATOR + MENUITEM "Smooth Accelerometer Graphs", ID_OPTIONS_SMOOTH + MENUITEM "Draw lines between data points",ID_OPTIONS_DRAWLINES + MENUITEM "Use dark background for plots",ID_OPTIONS_BACKGROUND MENUITEM SEPARATOR + MENUITEM "Force plotted data to fixed scales",ID_OPTIONS_IOIO5VSCALE + MENUITEM SEPARATOR MENUITEM "Plotting Options...",ID_OPTIONS_PLOTPREFS - - - END - POPUP "&Data" - BEGIN - MENUITEM "Switch Race Session", ID_DATA_SWITCHSESSION - MENUITEM "Open .wflp DB", ID_DATA_OPENDB - MENUITEM "Edit/Merge Race Sessions", ID_DATA_EDITSESSION - MENUITEM "Export selected laps to CSV format", ID_DATA_DASHWARE - END - POPUP "&Timing" - BEGIN - MENUITEM "Timing and Scoring", ID_TIMINGSCORING - END - POPUP "&Help" - BEGIN - MENUITEM "Show Pitside Help File", ID_HELP_SHOWHELP - MENUITEM "Show Wifilapper Help File", ID_HELP_SHOWWFLHELP - MENUITEM "Show IPs", ID_HELP_IPS - MENUITEM "About", ID_HELP_ABOUT - END -END + END + POPUP "&Phone Orientation" + BEGIN + MENUITEM "Vertical/Landscape", ID_OPTIONS_VERTICAL_LANDSCAPE + MENUITEM "Vertical/Portrait", ID_OPTIONS_VERTICAL_PORTRAIT + MENUITEM "Flat/Landscape", ID_OPTIONS_FLAT_LANDSCAPE + MENUITEM "Flat/Portrait", ID_OPTIONS_FLAT_PORTRAIT + END + POPUP "&Timing" + BEGIN + MENUITEM "Timing and Scoring", ID_TIMINGSCORING + END + POPUP "&Help" + BEGIN + MENUITEM "Show Pitside Help File", ID_HELP_SHOWHELP + MENUITEM "Show SpeedFreq Help File", ID_HELP_SHOWWFLHELP + MENUITEM "Show IPs", ID_HELP_IPS + MENUITEM "About", ID_HELP_ABOUT + END +END diff --git a/PitsideConsole/PitsideConsole/PitsideConsole.vcxproj b/PitsideConsole/PitsideConsole/PitsideConsole.vcxproj index 391b87c..884a2ca 100644 --- a/PitsideConsole/PitsideConsole/PitsideConsole.vcxproj +++ b/PitsideConsole/PitsideConsole/PitsideConsole.vcxproj @@ -123,9 +123,7 @@ copyjs_rel.bat - - @@ -153,9 +151,7 @@ copyjs_rel.bat - - diff --git a/PitsideConsole/PitsideConsole/PitsideConsole.vcxproj.filters b/PitsideConsole/PitsideConsole/PitsideConsole.vcxproj.filters index 1833a57..5f6b5ac 100644 --- a/PitsideConsole/PitsideConsole/PitsideConsole.vcxproj.filters +++ b/PitsideConsole/PitsideConsole/PitsideConsole.vcxproj.filters @@ -60,9 +60,6 @@ Header Files - - Header Files - Header Files @@ -105,9 +102,6 @@ Header Files - - Header Files - @@ -140,9 +134,6 @@ Source Files - - Source Files - Source Files @@ -185,9 +176,6 @@ Source Files - - Source Files - diff --git a/PitsideConsole/PitsideConsole/PitsideHelp.pdf b/PitsideConsole/PitsideConsole/PitsideHelp.pdf index b9a14f7..53d9955 100644 Binary files a/PitsideConsole/PitsideConsole/PitsideHelp.pdf and b/PitsideConsole/PitsideConsole/PitsideHelp.pdf differ diff --git a/PitsideConsole/PitsideConsole/SQLiteLapDB.cpp b/PitsideConsole/PitsideConsole/SQLiteLapDB.cpp index 9fae7d1..9d4275e 100644 --- a/PitsideConsole/PitsideConsole/SQLiteLapDB.cpp +++ b/PitsideConsole/PitsideConsole/SQLiteLapDB.cpp @@ -1,532 +1,534 @@ -#include "stdafx.h" -#include "LapReceiver.h" -#include "PitsideConsole.h" -#include "ArtUI.h" -#include "SQLiteLapDB.h" -#include "LapData.h" -class CSQLiteLap : public ILap -{ -public: - CSQLiteLap(CSfArtSQLiteDB& sfDB, ILapReceiver* pWriteBack) : m_sfDB(sfDB),m_pWriteBack(pWriteBack), m_fLoaded(false) {}; - virtual ~CSQLiteLap() {}; - -public: // ILap overrides - virtual void Load(V1InputLapRaw* pLap) override - { - DASSERT(false); // this should never be called - memory laps should be loaded instead. - } - virtual void Load(V2InputLapRaw* pLap) override - { - DASSERT(false); // this should never be called - memory laps should be loaded instead. - } - virtual bool Load(CSfArtSQLiteDB& db, StartFinish* rgSF, CSfArtSQLiteQuery& line) override - { - bool fSuccess = true; - fSuccess &= (line.GetCol(0, &m_iLapId)); - fSuccess &= (line.GetCol(1, &m_flLapTime)); - fSuccess &= (line.GetCol(2, &m_iStartTime)); - - TCHAR szComment[200]; - szComment[0] = 0; - fSuccess &= (line.GetCol(3, szComment, NUMCHARS(szComment))); - m_strComment = wstring(szComment); - - memcpy(this->m_rgSF, rgSF, sizeof(this->m_rgSF)); - - return fSuccess; - } - virtual void Free()override {delete this;}; - - virtual bool IsValid() const override {return m_flLapTime < 3600 && m_flLapTime > 3.0 && m_iLapId != -1;}; - virtual int GetStartTime() const override {return m_iStartTime;} - virtual int GetLapId() const override {return m_iLapId;} - virtual float GetTime() const override {return m_flLapTime;} - virtual wstring GetComment() const override {return m_strComment;} - virtual void SetComment(wstring strComment) const override - { - m_strComment = strComment; - m_pWriteBack->AddComment(m_iLapId,strComment.c_str()); - } - virtual const vector GetPoints() const override - { - vector lstPoints; - bool fSuccess = false; - // they're asking for points. This is where stuff gets expensive - // now we need to get all the datapoints for this lap (data channels will come later) - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"select points.x,points.y,points.time,points.velocity from points where points.lapid = %d", m_iLapId); - CSfArtSQLiteQuery sfPointQuery(m_sfDB); - if(sfPointQuery.Init(szQuery)) - { - while(sfPointQuery.Next()) - { - TimePoint2D pt; - fSuccess &= sfPointQuery.GetCol(0,&pt.flX); - fSuccess &= sfPointQuery.GetCol(1,&pt.flY); - fSuccess &= sfPointQuery.GetCol(2,&pt.iTime); - fSuccess &= sfPointQuery.GetCol(3,&pt.flVelocity); - pt.flSum = pt.flX + pt.flY; - DASSERT(pt.IsValid()); - if(pt.IsValid()) - { - lstPoints.push_back(pt); - } - } - } - return lstPoints; - } - virtual const StartFinish* GetSF() const override {return m_rgSF;} - virtual CARNUMBERCOMBO GetCarNumbers() const override - { - DASSERT(FALSE); // nobody should be calling this on an SQLite lap - CARNUMBERCOMBO sfCars; - sfCars.iCarNumber = -1; - sfCars.iSecondaryCarNumber = -1; - return sfCars; - } -public: // general CSQLiteLap functioning - -private: - CSfArtSQLiteDB& m_sfDB; - mutable ILapReceiver* m_pWriteBack; - - bool m_fLoaded; - - int m_iStartTime; - int m_iLapId; - float m_flLapTime; - mutable wstring m_strComment; -// StartFinish m_rgSF[3]; - StartFinish m_rgSF[50]; // Increased by KDJ -}; - -////////////////////////////////////////////////////////////// -static LPCTSTR CREATE_RACE_SQL_V20 = L"create table races ( _id integer primary key asc autoincrement, " \ - L"\"name\" string, " \ - L"\"date\" string, " \ - L"\"testmode\" integer, " \ - L"x1 real, " \ - L"y1 real, " \ - L"x2 real, " \ - L"y2 real, " \ - L"x3 real, " \ - L"y3 real, " \ - L"x4 real, " \ - L"y4 real, " \ - L"x5 real, " \ - L"y5 real, " \ - L"x6 real, " \ - L"y6 real, " \ - L"vx1 real," \ - L"vy1 real," \ - L"vx2 real," \ - L"vy2 real," \ - L"vx3 real," \ - L"vy3 real)"; - -static LPCTSTR CREATE_RACE_SQL_V21 = L"create table races ( _id integer primary key asc autoincrement, " \ - L"\"name\" string, " \ - L"\"date\" string, " \ - L"\"testmode\" integer, " \ - L"x1 real, " \ - L"y1 real, " \ - L"x2 real, " \ - L"y2 real, " \ - L"x3 real, " \ - L"y3 real, " \ - L"x4 real, " \ - L"y4 real, " \ - L"x5 real, " \ - L"y5 real, " \ - L"x6 real, " \ - L"y6 real, " \ - L"vx1 real," \ - L"vy1 real," \ - L"vx2 real," \ - L"vy2 real," \ - L"vx3 real," \ - L"vy3 real," \ - L"p2p integer not null default 0)"; - -static LPCTSTR CREATE_RACE_SQL_V22 = L"create table races ( _id integer primary key asc autoincrement, " \ - L"\"name\" string, " \ - L"\"date\" string, " \ - L"\"testmode\" integer, " \ - L"x1 real, " \ - L"y1 real, " \ - L"x2 real, " \ - L"y2 real, " \ - L"x3 real, " \ - L"y3 real, " \ - L"x4 real, " \ - L"y4 real, " \ - L"x5 real, " \ - L"y5 real, " \ - L"x6 real, " \ - L"y6 real, " \ - L"vx1 real," \ - L"vy1 real," \ - L"vx2 real," \ - L"vy2 real," \ - L"vx3 real," \ - L"vy3 real," \ - L"p2p integer not null default 0," \ - L"finishcount integer not null default 1)"; - -static LPCTSTR CREATE_LAPS_SQL = L"create table laps " \ - L"(_id integer primary key asc autoincrement, " \ - L"laptime real, " \ - L"unixtime integer, " \ - L"transmitted integer, " \ - L"raceid integer," \ - L"foreign key (raceid) references races(_id))"; - -static LPCTSTR CREATE_POINTS_SQL = L"create table points " \ - L"(_id integer primary key asc autoincrement, " \ - L"x real," \ - L"y real," \ - L"time integer," \ - L"velocity real," \ - L"lapid integer," \ - L"foreign key (lapid) references laps(_id))"; - -static LPCTSTR CREATE_CHANNELS_SQL = L"create table channels" \ - L"(_id integer primary key asc autoincrement, " \ - L"lapid integer NOT NULL," \ - L"channeltype integer NOT NULL," \ - L"foreign key(lapid) references laps(_id))"; - -static LPCTSTR CREATE_DATA_SQL =L"create table data " \ - L"(_id integer primary key asc autoincrement," \ - L"time integer NOT NULL," \ - L"value real NOT NULL," \ - L"channelid integer NOT NULL," \ - L"foreign key (channelid) references channels(_id))"; - -static LPCTSTR CREATE_EXTRA_SQL =L"create table extras " \ - L"(_id integer primary key asc autoincrement," \ - L"comment string," \ - L"lapid integer NOT NULL unique on conflict fail," \ - L"foreign key (lapid) references laps(_id))"; - -static LPCTSTR CREATE_INDICES =L"create index data_channelid on data(channelid);" \ - L"create index if not exists points_lapid on points(lapid);" \ - L"create index if not exists laps_raceid on laps(raceid)"; - -static LPCTSTR rgRequiredTables20[] = {CREATE_RACE_SQL_V20, CREATE_LAPS_SQL, CREATE_POINTS_SQL, CREATE_CHANNELS_SQL, CREATE_DATA_SQL, NULL}; -static LPCTSTR rgRequiredTables21[] = {CREATE_RACE_SQL_V21, CREATE_LAPS_SQL, CREATE_POINTS_SQL, CREATE_CHANNELS_SQL, CREATE_DATA_SQL, NULL}; -static LPCTSTR rgRequiredTables23[] = {CREATE_RACE_SQL_V22, CREATE_LAPS_SQL, CREATE_POINTS_SQL, CREATE_CHANNELS_SQL, CREATE_DATA_SQL, CREATE_EXTRA_SQL}; - -static LPCTSTR* rgSchemaList[] = -{ - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables20, - rgRequiredTables21, - rgRequiredTables21, - rgRequiredTables23 -}; - -const static int iMinSupportedVersion = 0; -const static int iMaxSupportedVersion = 23; -////////////////////////////////////////////////////////////// -bool CSQLiteLapDB::Init(LPCTSTR lpszPath) -{ - if(!DoesFileExist(lpszPath)) - { - vector lstSQL; - HRESULT hr = m_sfDB.Open(lpszPath, lstSQL); - if(SUCCEEDED(hr)) - { - for(int x = 0;x < 6; x++) - { - hr = E_FAIL; - CSfArtSQLiteQuery sfInsert(m_sfDB); - if(sfInsert.Init(rgSchemaList[iMaxSupportedVersion][x])) - { - if(sfInsert.Next()) - { - hr = S_OK; - } - if(sfInsert.IsDone()) - { - hr = S_OK; - } - } - if(FAILED(hr)) - break; - } - } - return SUCCEEDED(hr); - } - else - { - int iFindFailures = 0; - int ixFoundVersion = -1; - vector lstSQL; - HRESULT hr = m_sfDB.Open(lpszPath, lstSQL); - if(SUCCEEDED(hr)) - { - // find a schema version that matches - for(int ixVersion = iMaxSupportedVersion; ixVersion >= iMinSupportedVersion; ixVersion--) - { - bool fFoundAll = true; - for(int x = 0; x < 6 && fFoundAll; x++) - { - // we want to find rgSchemaList[ixVersion][x] in the lstSQL that we got from the DB. - if(!rgSchemaList[ixVersion][x]) continue; // don't need to find this one - - bool fFound = false; - for(int y = 0; y < lstSQL.size(); y++) - { - if(wcsstr(lstSQL[y].c_str(),L"android_metadata") != NULL) continue; // don't care about this table - if(nospacecompare(lstSQL[y].c_str(),rgSchemaList[ixVersion][x]) == 0) - { - fFound = true; - break; - } - } - if(!fFound) - { - iFindFailures++; - } - - fFoundAll = fFoundAll && fFound; - } - if(fFoundAll) - { - ixFoundVersion = ixVersion; - break; - } - } - - if(ixFoundVersion < 0) - { - DASSERT(FALSE); - // we didn't find or create all our required tables... - hr = E_FAIL; - } - - - if(SUCCEEDED(hr) && ixFoundVersion < 23) - { - // upgrade! - CSfArtSQLiteQuery sfQuery(m_sfDB); - if(sfQuery.Init(CREATE_EXTRA_SQL)) - { - while(sfQuery.Next()) - { - } - DASSERT(sfQuery.IsDone()); - } - } - /*if(ixFoundVersion < ...) future upgrades... - { - }*/ - } - return SUCCEEDED(hr); - } - -} -////////////////////////////////////////////////////////////// -bool CSQLiteLapDB::InitRaceSession(int* piRaceId, LPCTSTR lpszRaceName) -{ - AutoLeaveCS _cs(&m_cs); - bool fSuccess = true; - CSfArtSQLiteQuery sfQuery(m_sfDB); - if(sfQuery.Init(L"insert into races (name,date) values (?,?)")) - { - sfQuery.BindValue(lpszRaceName); - sfQuery.BindValue(GetSecondsSince1970()); - if(sfQuery.Next() || sfQuery.IsDone()) - { - // inserted new data, hooray! - long long lastInsert = m_sfDB.GetLastInsertId(); - *piRaceId = lastInsert; - return true; - } - } - return false; -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::DeInit() -{ - AutoLeaveCS _cs(&m_cs); - m_sfDB.Close(); -} -////////////////////////////////////////////////////////////// -ILap* CSQLiteLapDB::AllocateLap(bool fMemory) -{ - if(fMemory) - { - return new CMemoryLap(); - } - else - { - return new CSQLiteLap(m_sfDB, this); - } -} -////////////////////////////////////////////////////////////// -IDataChannel* CSQLiteLapDB::AllocateDataChannel() const -{ - AutoLeaveCS _cs(&m_cs); - cChannels++; - return new CDataChannel(); -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::FreeDataChannel(IDataChannel* pChannel) const -{ - AutoLeaveCS _cs(&m_cs); - cChannels--; - delete pChannel; -} -////////////////////////////////////////////////////////////// -int CSQLiteLapDB::GetLastReceivedRaceId() const -{ - AutoLeaveCS _cs(&m_cs); - DASSERT(m_iLastRaceId >= 0); // you shouldn't be calling this unless there's evidence we've received a lap! - return m_iLastRaceId; -} -////////////////////////////////////////////////////////////// -bool CSQLiteLapDB::IsActivelyReceiving(int iRaceId) const -{ - AutoLeaveCS _cs(&m_cs); - return this->m_setReceivingIds.find(iRaceId) != m_setReceivingIds.end(); -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::GetLastLapTimeStamp(const vector& lstCarNumbers, vector& lstTimeStamps) const -{ - AutoLeaveCS _cs(&m_cs); - for(int x = 0;x < lstCarNumbers.size(); x++) - { - const int iCar = lstCarNumbers[x]; - unsigned int msLatestTime = 0; - { - for(map::const_iterator i = mapCarNumberRaceIds.begin(); i != mapCarNumberRaceIds.end(); i++) - { - if(i->first.iCarNumber == iCar) - { - const int iRaceId = i->second; - map::const_iterator found = mapLastRaceTimes.find(iRaceId); - if(found != mapLastRaceTimes.end()) - { - const int msLastLapTime = found->second; - msLatestTime = max(msLatestTime, msLastLapTime); // figures out which one came later - } - else - { - // nothing to do, this race doesn't have a last lap time - } - } - } - lstTimeStamps.push_back(msLatestTime); - } - } -} -////////////////////////////////////////////////////////////// -vector CSQLiteLapDB::GetScoring(int iRaceId) -{ - AutoLeaveCS _cs(&m_cs); - vector lstLaps; - // gotta load all the laps that are in the DB, but we don't want to fully load them, just their laptimes and other directly lap-related data - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"Select laps._id,laps.laptime, laps.unixtime,extras.comment from laps left join extras on extras.lapid = laps._id where laps.raceid=%d", iRaceId); - if(sfQuery.Init(szQuery)) - { - while(sfQuery.Next()) - { - CSQLiteLap* pLap = (CSQLiteLap*)AllocateLap(false); - pLap->Load(m_sfDB,m_rgSF,sfQuery); - if(pLap->IsValid()) - { - lstLaps.push_back(pLap); - } - } - } - return lstLaps; -} -////////////////////////////////////////////////////////////// -int CSQLiteLapDB::GetLapCount(int iRaceId) const -{ - AutoLeaveCS _cs(&m_cs); - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"select count(laps._id) from races,laps where races._id = %d and laps.raceid=races._id group by races._id", iRaceId); - - if(sfQuery.Init(szQuery)) - { - while(sfQuery.Next()) - { - int cLaps = 0; - if(sfQuery.GetCol(0,&cLaps)) - { - return cLaps; - } - } - } - return 0; -} -////////////////////////////////////////////////////////////// -vector CSQLiteLapDB::GetRaces() -{ - AutoLeaveCS _cs(&m_cs); - vector lstRaces; - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"select races.name,races.date,count(laps._id),races._id from races,laps where laps.raceid=races._id group by races._id"); - - if(sfQuery.Init(szQuery)) - { - while(sfQuery.Next()) - { - RACEDATA raceData; - TCHAR szData[1000]; - if(sfQuery.GetCol(0,szData,NUMCHARS(szData))) - { - raceData.strName = szData; - int iRaceDate = 0; - if(sfQuery.GetCol(1,&iRaceDate)) - { - raceData.unixtime = iRaceDate; - } - int cLaps = 0; - if(sfQuery.GetCol(2,&cLaps)) - { - raceData.laps = cLaps; - } - int iRaceId = 0; - if(sfQuery.GetCol(3,&iRaceId)) - { - raceData.raceId = iRaceId; - } - lstRaces.push_back(raceData); - } - } - } - return lstRaces; -} -////////////////////////////////////////////////////////////// -bool CSQLiteLapDB::MergeLaps(int m_iRaceId1, int m_iRaceId2) -{ +#include "stdafx.h" +#include "LapReceiver.h" +#include "PitsideConsole.h" +#include "ArtUI.h" +#include "SQLiteLapDB.h" +#include "LapData.h" +class CSQLiteLap : public ILap +{ +public: + vector vLastLapId; + + CSQLiteLap(CSfArtSQLiteDB& sfDB, ILapReceiver* pWriteBack) : m_sfDB(sfDB),m_pWriteBack(pWriteBack), m_fLoaded(false) {}; + virtual ~CSQLiteLap() {}; + +public: // ILap overrides + virtual void Load(V1InputLapRaw* pLap) override + { + DASSERT(false); // this should never be called - memory laps should be loaded instead. + } + virtual void Load(V2InputLapRaw* pLap) override + { + DASSERT(false); // this should never be called - memory laps should be loaded instead. + } + virtual bool Load(CSfArtSQLiteDB& db, StartFinish* rgSF, CSfArtSQLiteQuery& line) override + { + bool fSuccess = true; + fSuccess &= (line.GetCol(0, &m_iLapId)); + fSuccess &= (line.GetCol(1, &m_flLapTime)); + fSuccess &= (line.GetCol(2, &m_iStartTime)); + + TCHAR szComment[200]; + szComment[0] = 0; + fSuccess &= (line.GetCol(3, szComment, NUMCHARS(szComment))); + m_strComment = wstring(szComment); + + memcpy(this->m_rgSF, rgSF, sizeof(this->m_rgSF)); + + return fSuccess; + } + virtual void Free()override {delete this;}; + + virtual bool IsValid() const override {return m_flLapTime < 3600 && m_flLapTime > 3.0 && m_iLapId != -1;}; + virtual int GetStartTime() const override {return m_iStartTime;} + virtual int GetLapId() const override {return m_iLapId;} + virtual float GetTime() const override {return m_flLapTime;} + virtual wstring GetComment() const override {return m_strComment;} + virtual void SetComment(wstring strComment) const override + { + m_strComment = strComment; + m_pWriteBack->AddComment(m_iLapId,strComment.c_str()); + } + virtual const vector GetPoints() const override + { + vector lstPoints; + bool fSuccess = false; + // they're asking for points. This is where stuff gets expensive + // now we need to get all the datapoints for this lap (data channels will come later) + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"select points.x,points.y,points.time,points.velocity from points where points.lapid = %d", m_iLapId); + CSfArtSQLiteQuery sfPointQuery(m_sfDB); + if(sfPointQuery.Init(szQuery)) + { + while(sfPointQuery.Next()) + { + TimePoint2D pt; + fSuccess &= sfPointQuery.GetCol(0,&pt.flX); + fSuccess &= sfPointQuery.GetCol(1,&pt.flY); + fSuccess &= sfPointQuery.GetCol(2,&pt.iTime); + fSuccess &= sfPointQuery.GetCol(3,&pt.flVelocity); + pt.flSum = pt.flX + pt.flY; + DASSERT(pt.IsValid()); + if(pt.IsValid()) + { + lstPoints.push_back(pt); + } + } + } + return lstPoints; + } + virtual const StartFinish* GetSF() const override {return m_rgSF;} + virtual CARNUMBERCOMBO GetCarNumbers() const override + { + DASSERT(FALSE); // nobody should be calling this on an SQLite lap + CARNUMBERCOMBO sfCars; + sfCars.iCarNumber = -1; + sfCars.iSecondaryCarNumber = -1; + return sfCars; + } +public: // general CSQLiteLap functioning + +private: + CSfArtSQLiteDB& m_sfDB; + mutable ILapReceiver* m_pWriteBack; + + bool m_fLoaded; + + int m_iStartTime; + int m_iLapId; + float m_flLapTime; + mutable wstring m_strComment; +// StartFinish m_rgSF[3]; + StartFinish m_rgSF[50]; // Increased by KDJ +}; + +////////////////////////////////////////////////////////////// +static LPCTSTR CREATE_RACE_SQL_V20 = L"create table races ( _id integer primary key asc autoincrement, " \ + L"\"name\" string, " \ + L"\"date\" string, " \ + L"\"testmode\" integer, " \ + L"x1 real, " \ + L"y1 real, " \ + L"x2 real, " \ + L"y2 real, " \ + L"x3 real, " \ + L"y3 real, " \ + L"x4 real, " \ + L"y4 real, " \ + L"x5 real, " \ + L"y5 real, " \ + L"x6 real, " \ + L"y6 real, " \ + L"vx1 real," \ + L"vy1 real," \ + L"vx2 real," \ + L"vy2 real," \ + L"vx3 real," \ + L"vy3 real)"; + +static LPCTSTR CREATE_RACE_SQL_V21 = L"create table races ( _id integer primary key asc autoincrement, " \ + L"\"name\" string, " \ + L"\"date\" string, " \ + L"\"testmode\" integer, " \ + L"x1 real, " \ + L"y1 real, " \ + L"x2 real, " \ + L"y2 real, " \ + L"x3 real, " \ + L"y3 real, " \ + L"x4 real, " \ + L"y4 real, " \ + L"x5 real, " \ + L"y5 real, " \ + L"x6 real, " \ + L"y6 real, " \ + L"vx1 real," \ + L"vy1 real," \ + L"vx2 real," \ + L"vy2 real," \ + L"vx3 real," \ + L"vy3 real," \ + L"p2p integer not null default 0)"; + +static LPCTSTR CREATE_RACE_SQL_V22 = L"create table races ( _id integer primary key asc autoincrement, " \ + L"\"name\" string, " \ + L"\"date\" string, " \ + L"\"testmode\" integer, " \ + L"x1 real, " \ + L"y1 real, " \ + L"x2 real, " \ + L"y2 real, " \ + L"x3 real, " \ + L"y3 real, " \ + L"x4 real, " \ + L"y4 real, " \ + L"x5 real, " \ + L"y5 real, " \ + L"x6 real, " \ + L"y6 real, " \ + L"vx1 real," \ + L"vy1 real," \ + L"vx2 real," \ + L"vy2 real," \ + L"vx3 real," \ + L"vy3 real," \ + L"p2p integer not null default 0," \ + L"finishcount integer not null default 1)"; + +static LPCTSTR CREATE_LAPS_SQL = L"create table laps " \ + L"(_id integer primary key asc autoincrement, " \ + L"laptime real, " \ + L"unixtime integer, " \ + L"transmitted integer, " \ + L"raceid integer," \ + L"foreign key (raceid) references races(_id))"; + +static LPCTSTR CREATE_POINTS_SQL = L"create table points " \ + L"(_id integer primary key asc autoincrement, " \ + L"x real," \ + L"y real," \ + L"time integer," \ + L"velocity real," \ + L"lapid integer," \ + L"foreign key (lapid) references laps(_id))"; + +static LPCTSTR CREATE_CHANNELS_SQL = L"create table channels" \ + L"(_id integer primary key asc autoincrement, " \ + L"lapid integer NOT NULL," \ + L"channeltype integer NOT NULL," \ + L"foreign key(lapid) references laps(_id))"; + +static LPCTSTR CREATE_DATA_SQL =L"create table data " \ + L"(_id integer primary key asc autoincrement," \ + L"time integer NOT NULL," \ + L"value real NOT NULL," \ + L"channelid integer NOT NULL," \ + L"foreign key (channelid) references channels(_id))"; + +static LPCTSTR CREATE_EXTRA_SQL =L"create table extras " \ + L"(_id integer primary key asc autoincrement," \ + L"comment string," \ + L"lapid integer NOT NULL unique on conflict fail," \ + L"foreign key (lapid) references laps(_id))"; + +static LPCTSTR CREATE_INDICES =L"create index data_channelid on data(channelid);" \ + L"create index if not exists points_lapid on points(lapid);" \ + L"create index if not exists laps_raceid on laps(raceid)"; + +static LPCTSTR rgRequiredTables20[] = {CREATE_RACE_SQL_V20, CREATE_LAPS_SQL, CREATE_POINTS_SQL, CREATE_CHANNELS_SQL, CREATE_DATA_SQL, NULL}; +static LPCTSTR rgRequiredTables21[] = {CREATE_RACE_SQL_V21, CREATE_LAPS_SQL, CREATE_POINTS_SQL, CREATE_CHANNELS_SQL, CREATE_DATA_SQL, NULL}; +static LPCTSTR rgRequiredTables23[] = {CREATE_RACE_SQL_V22, CREATE_LAPS_SQL, CREATE_POINTS_SQL, CREATE_CHANNELS_SQL, CREATE_DATA_SQL, CREATE_EXTRA_SQL}; + +static LPCTSTR* rgSchemaList[] = +{ + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables20, + rgRequiredTables21, + rgRequiredTables21, + rgRequiredTables23 +}; + +const static int iMinSupportedVersion = 0; +const static int iMaxSupportedVersion = 23; +////////////////////////////////////////////////////////////// +bool CSQLiteLapDB::Init(LPCTSTR lpszPath) +{ + if(!DoesFileExist(lpszPath)) + { + vector lstSQL; + HRESULT hr = m_sfDB.Open(lpszPath, lstSQL); + if(SUCCEEDED(hr)) + { + for(int x = 0;x < 6; x++) + { + hr = E_FAIL; + CSfArtSQLiteQuery sfInsert(m_sfDB); + if(sfInsert.Init(rgSchemaList[iMaxSupportedVersion][x])) + { + if(sfInsert.Next()) + { + hr = S_OK; + } + if(sfInsert.IsDone()) + { + hr = S_OK; + } + } + if(FAILED(hr)) + break; + } + } + return SUCCEEDED(hr); + } + else + { + int iFindFailures = 0; + int ixFoundVersion = -1; + vector lstSQL; + HRESULT hr = m_sfDB.Open(lpszPath, lstSQL); + if(SUCCEEDED(hr)) + { + // find a schema version that matches + for(int ixVersion = iMaxSupportedVersion; ixVersion >= iMinSupportedVersion; ixVersion--) + { + bool fFoundAll = true; + for(int x = 0; x < 6 && fFoundAll; x++) + { + // we want to find rgSchemaList[ixVersion][x] in the lstSQL that we got from the DB. + if(!rgSchemaList[ixVersion][x]) continue; // don't need to find this one + + bool fFound = false; + for(int y = 0; y < lstSQL.size(); y++) + { + if(wcsstr(lstSQL[y].c_str(),L"android_metadata") != NULL) continue; // don't care about this table + if(nospacecompare(lstSQL[y].c_str(),rgSchemaList[ixVersion][x]) == 0) + { + fFound = true; + break; + } + } + if(!fFound) + { + iFindFailures++; + } + + fFoundAll = fFoundAll && fFound; + } + if(fFoundAll) + { + ixFoundVersion = ixVersion; + break; + } + } + + if(ixFoundVersion < 0) + { + DASSERT(FALSE); + // we didn't find or create all our required tables... + hr = E_FAIL; + } + + + if(SUCCEEDED(hr) && ixFoundVersion < 23) + { + // upgrade! + CSfArtSQLiteQuery sfQuery(m_sfDB); + if(sfQuery.Init(CREATE_EXTRA_SQL)) + { + while(sfQuery.Next()) + { + } + DASSERT(sfQuery.IsDone()); + } + } + /*if(ixFoundVersion < ...) future upgrades... + { + }*/ + } + return SUCCEEDED(hr); + } + +} +////////////////////////////////////////////////////////////// +bool CSQLiteLapDB::InitRaceSession(int* piRaceId, LPCTSTR lpszRaceName) +{ + AutoLeaveCS _cs(&m_cs); + bool fSuccess = true; + CSfArtSQLiteQuery sfQuery(m_sfDB); + if(sfQuery.Init(L"insert into races (name,date) values (?,?)")) + { + sfQuery.BindValue(lpszRaceName); + sfQuery.BindValue(GetSecondsSince1970()); + if(sfQuery.Next() || sfQuery.IsDone()) + { + // inserted new data, hooray! + long long lastInsert = m_sfDB.GetLastInsertId(); + *piRaceId = lastInsert; + return true; + } + } + return false; +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::DeInit() +{ + AutoLeaveCS _cs(&m_cs); + m_sfDB.Close(); +} +////////////////////////////////////////////////////////////// +ILap* CSQLiteLapDB::AllocateLap(bool fMemory) +{ + if(fMemory) + { + return new CMemoryLap(); + } + else + { + return new CSQLiteLap(m_sfDB, this); + } +} +////////////////////////////////////////////////////////////// +IDataChannel* CSQLiteLapDB::AllocateDataChannel() const +{ + AutoLeaveCS _cs(&m_cs); + cChannels++; + return new CDataChannel(); +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::FreeDataChannel(IDataChannel* pChannel) const +{ + AutoLeaveCS _cs(&m_cs); + cChannels--; + delete pChannel; +} +////////////////////////////////////////////////////////////// +int CSQLiteLapDB::GetLastReceivedRaceId() const +{ + AutoLeaveCS _cs(&m_cs); + DASSERT(m_iLastRaceId >= 0); // you shouldn't be calling this unless there's evidence we've received a lap! + return m_iLastRaceId; +} +////////////////////////////////////////////////////////////// +bool CSQLiteLapDB::IsActivelyReceiving(int iRaceId) const +{ + AutoLeaveCS _cs(&m_cs); + return this->m_setReceivingIds.find(iRaceId) != m_setReceivingIds.end(); +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::GetLastLapTimeStamp(const vector& lstCarNumbers, vector& lstTimeStamps) const +{ + AutoLeaveCS _cs(&m_cs); + for(int x = 0;x < lstCarNumbers.size(); x++) + { + const int iCar = lstCarNumbers[x]; + unsigned int msLatestTime = 0; + { + for(map::const_iterator i = mapCarNumberRaceIds.begin(); i != mapCarNumberRaceIds.end(); i++) + { + if(i->first.iCarNumber == iCar) + { + const int iRaceId = i->second; + map::const_iterator found = mapLastRaceTimes.find(iRaceId); + if(found != mapLastRaceTimes.end()) + { + const int msLastLapTime = found->second; + msLatestTime = max(msLatestTime, msLastLapTime); // figures out which one came later + } + else + { + // nothing to do, this race doesn't have a last lap time + } + } + } + lstTimeStamps.push_back(msLatestTime); + } + } +} +////////////////////////////////////////////////////////////// +vector CSQLiteLapDB::GetScoring(int iRaceId) +{ + AutoLeaveCS _cs(&m_cs); + vector lstLaps; + // gotta load all the laps that are in the DB, but we don't want to fully load them, just their laptimes and other directly lap-related data + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"Select laps._id,laps.laptime, laps.unixtime,extras.comment from laps left join extras on extras.lapid = laps._id where laps.raceid=%d", iRaceId); + if(sfQuery.Init(szQuery)) + { + while(sfQuery.Next()) + { + CSQLiteLap* pLap = (CSQLiteLap*)AllocateLap(false); + pLap->Load(m_sfDB,m_rgSF,sfQuery); + if(pLap->IsValid()) + { + lstLaps.push_back(pLap); + } + } + } + return lstLaps; +} +////////////////////////////////////////////////////////////// +int CSQLiteLapDB::GetLapCount(int iRaceId) const +{ + AutoLeaveCS _cs(&m_cs); + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"select count(laps._id) from races,laps where races._id = %d and laps.raceid=races._id group by races._id", iRaceId); + + if(sfQuery.Init(szQuery)) + { + while(sfQuery.Next()) + { + int cLaps = 0; + if(sfQuery.GetCol(0,&cLaps)) + { + return cLaps; + } + } + } + return 0; +} +////////////////////////////////////////////////////////////// +vector CSQLiteLapDB::GetRaces() +{ + AutoLeaveCS _cs(&m_cs); + vector lstRaces; + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"select races.name,races.date,count(laps._id),races._id from races,laps where laps.raceid=races._id group by races._id"); + + if(sfQuery.Init(szQuery)) + { + while(sfQuery.Next()) + { + RACEDATA raceData; + TCHAR szData[1000]; + if(sfQuery.GetCol(0,szData,NUMCHARS(szData))) + { + raceData.strName = szData; + int iRaceDate = 0; + if(sfQuery.GetCol(1,&iRaceDate)) + { + raceData.unixtime = iRaceDate; + } + int cLaps = 0; + if(sfQuery.GetCol(2,&cLaps)) + { + raceData.laps = cLaps; + } + int iRaceId = 0; + if(sfQuery.GetCol(3,&iRaceId)) + { + raceData.raceId = iRaceId; + } + lstRaces.push_back(raceData); + } + } + } + return lstRaces; +} +////////////////////////////////////////////////////////////// +bool CSQLiteLapDB::MergeLaps(int m_iRaceId1, int m_iRaceId2) +{ CSfArtSQLiteQuery sfQuery(m_sfDB); if(sfQuery.Init(L"Update laps set raceid = ? where raceid = ?")) { @@ -538,11 +540,11 @@ bool CSQLiteLapDB::MergeLaps(int m_iRaceId1, int m_iRaceId2) return true; } } - return false; -} -////////////////////////////////////////////////////////////// -bool CSQLiteLapDB::RenameLaps(TCHAR szName[MAX_PATH], int m_iRaceId1) -{ + return false; +} +////////////////////////////////////////////////////////////// +bool CSQLiteLapDB::RenameLaps(TCHAR szName[MAX_PATH], int m_iRaceId1) +{ CSfArtSQLiteQuery sfQuery(m_sfDB); if(sfQuery.Init(L"update races set name = ? where _id = ?")) { @@ -554,304 +556,321 @@ bool CSQLiteLapDB::RenameLaps(TCHAR szName[MAX_PATH], int m_iRaceId1) return true; } } - return false; -} -////////////////////////////////////////////////////////////// -vector CSQLiteLapDB::GetLaps(int iRaceId) -{ - AutoLeaveCS _cs(&m_cs); - vector lstLaps; - // gotta load all the laps that are in the DB, but we don't want to fully load them, just their laptimes and other directly lap-related data - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"Select laps._id,laps.laptime, laps.unixtime,extras.comment from laps left join extras on extras.lapid = laps._id where laps.raceid=%d", iRaceId); - if(sfQuery.Init(szQuery)) - { - while(sfQuery.Next()) - { - CSQLiteLap* pLap = (CSQLiteLap*)AllocateLap(false); - pLap->Load(m_sfDB,m_rgSF,sfQuery); - if(pLap->IsValid()) - { - lstLaps.push_back(pLap); - } - } - } - return lstLaps; -} -////////////////////////////////////////////////////////////// -const ILap* CSQLiteLapDB::GetLap(int iLapId) -{ - AutoLeaveCS _cs(&m_cs); - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"Select laps._id,laps.laptime, laps.unixtime from laps where laps._id = %d", iLapId); - if(sfQuery.Init(szQuery)) - { - if(sfQuery.Next()) - { - CSQLiteLap* pLap = (CSQLiteLap*)AllocateLap(false); - pLap->Load(m_sfDB,m_rgSF,sfQuery); - - return pLap; - } - } - return NULL; -} -////////////////////////////////////////////////////////////// -const IDataChannel* CSQLiteLapDB::GetDataChannel(int iLapId, DATA_CHANNEL eChannel) const -{ - AutoLeaveCS _cs(&m_cs); - if(eChannel == DATA_CHANNEL_VELOCITY) - { - // since velocity is stored as part of the points table, it is a bit different than the normal data channels - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"select points.time, points.velocity from points where lapid=%d", iLapId); - if(sfQuery.Init(szQuery)) - { - IDataChannel* pChannel = AllocateDataChannel(); - pChannel->Init(iLapId,DATA_CHANNEL_VELOCITY); - while(sfQuery.Next()) - { - int iTime = 0; - double dVel = 0; - if(sfQuery.GetCol(0,&iTime) && sfQuery.GetCol(1,&dVel)) - { - pChannel->AddPoint(iTime, dVel); - } - } - pChannel->Lock(); - return pChannel; - } - } - else - { - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"select channels._id, channels.lapid, channels.channeltype from channels where channels.lapid = %d and channels.channeltype=%d", iLapId, eChannel); - if(sfQuery.Init(szQuery)) - { - if(sfQuery.Next()) - { - IDataChannel* pChannel = AllocateDataChannel(); - pChannel->Load(m_sfDB,sfQuery,true); - // warning: massive memory leaks here - return pChannel; - } - } - } - return NULL; -} -////////////////////////////////////////////////////////////// -set CSQLiteLapDB::GetAvailableChannels(int iLapId) const -{ - AutoLeaveCS _cs(&m_cs); - set setRet; - - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"select channels.channeltype from channels where channels.lapid = %d", iLapId); - if(sfQuery.Init(szQuery)) - { - while(sfQuery.Next()) - { - DATA_CHANNEL eType; - if(sfQuery.GetCol(0,(int*)&eType)) - { - setRet.insert(eType); - } - } - } - return setRet; -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::GetComments(int iLapId, vector& lstComments) const -{ - AutoLeaveCS _cs(&m_cs); - CSfArtSQLiteQuery sfQuery(m_sfDB); - TCHAR szQuery[MAX_PATH]; - _snwprintf(szQuery, NUMCHARS(szQuery), L"select extras.comment from extras where extras.lapid = %d", iLapId); - if(sfQuery.Init(szQuery)) - { - while(sfQuery.Next()) - { - TCHAR szComment[500]; - if(sfQuery.GetCol(0,szComment, NUMCHARS(szComment))) - { - lstComments.push_back(szComment); - } - } - } -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::AddLap(const ILap* pLap, int _iRaceId) -{ - AutoLeaveCS _cs(&m_cs); - CARNUMBERCOMBO sfCarNumber = pLap->GetCarNumbers(); - int iSaveRaceId = -1; - if(mapCarNumberRaceIds.find(sfCarNumber) == mapCarNumberRaceIds.end()) - { - // we've never seen this car number combo before. Time for a new race. - TCHAR szRaceName[200]; - if(sfCarNumber.IsOldVersion()) - { - _snwprintf(szRaceName,NUMCHARS(szRaceName),L"Received from old wifilappers"); - } - else - { - _snwprintf(szRaceName,NUMCHARS(szRaceName),L"Received laps (car %d) - (%d)", sfCarNumber.iCarNumber, sfCarNumber.iSecondaryCarNumber); - } - int iNewRaceId = -1; - if(InitRaceSession(&iNewRaceId,szRaceName)) - { - mapCarNumberRaceIds[sfCarNumber] = iNewRaceId; - iSaveRaceId = iNewRaceId; - } - else - { - return; - } - } - else - { - iSaveRaceId = mapCarNumberRaceIds[sfCarNumber]; - } - - m_setReceivingIds.insert(iSaveRaceId); // this race ID received a lap - m_iLastRaceId = iSaveRaceId; - - m_sfDB.StartTransaction(); - - bool fSuccess = true; - CSfArtSQLiteQuery sfQuery(m_sfDB); - if(sfQuery.Init(L"insert into laps (_id,laptime,unixtime,transmitted,raceid) values (?,?,?,?,?)")) - { - sfQuery.BindValue(pLap->GetLapId()); - sfQuery.BindValue(pLap->GetTime()); - sfQuery.BindValue(pLap->GetStartTime()); - sfQuery.BindValue(0); - sfQuery.BindValue(iSaveRaceId); - if(sfQuery.Next() || sfQuery.IsDone()) - { - // inserted new data, hooray! - - vector lstPoints = pLap->GetPoints(); - for(int x = 0;x < lstPoints.size(); x++) - { - const TimePoint2D& pt = lstPoints[x]; - sfQuery.DeInit(); - if(sfQuery.Init(L"insert into points (x,y,time,velocity,lapid) values (?,?,?,?,?)")) - { - sfQuery.BindValue(pt.flX); - sfQuery.BindValue(pt.flY); - sfQuery.BindValue(pt.iTime); - sfQuery.BindValue(pt.flVelocity); - sfQuery.BindValue(pLap->GetLapId()); - if(!sfQuery.Next() && !sfQuery.IsDone()) - { - fSuccess = false; - break; - } - } - } - } - else - { - fSuccess = false; - } - } - - if(fSuccess) - { - mapLastRaceTimes[iSaveRaceId] = timeGetTime(); - m_pUI->NotifyChange(NOTIFY_NEWLAP,(LPARAM)this); - } - - m_sfDB.StopTransaction(); -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::AddDataChannel(const IDataChannel* pChannel) -{ - AutoLeaveCS _cs(&m_cs); - m_sfDB.StartTransaction(); - - bool fSuccess = true; - CSfArtSQLiteQuery sfQuery(m_sfDB); - if(sfQuery.Init(L"insert into channels (lapid,channeltype) values (?,?)")) - { - sfQuery.BindValue(pChannel->GetLapId()); - sfQuery.BindValue((int)pChannel->GetChannelType()); - if(sfQuery.Next() || sfQuery.IsDone()) - { - // inserted new data, hooray! - long long lastInsert = m_sfDB.GetLastInsertId(); - - - vector lstPoints = pChannel->GetData(); - for(int x = 0;x < lstPoints.size(); x++) - { - const DataPoint& pt = lstPoints[x]; - sfQuery.DeInit(); - if(sfQuery.Init(L"insert into data (time,value,channelid) values (?,?,?)")) - { - sfQuery.BindValue(pt.iTimeMs); - sfQuery.BindValue(pt.flValue); - sfQuery.BindValue(lastInsert); - if(!sfQuery.Next() && !sfQuery.IsDone()) - { - fSuccess = false; - break; - } - } - } - } - else - { - fSuccess = false; - } - } - if(fSuccess) - { - m_pUI->NotifyChange(NOTIFY_NEWDATA,(LPARAM)this); - } - - m_sfDB.StopTransaction(); -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::Clear() -{ -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::AddComment(int iLapId, LPCTSTR strComment) -{ - CSfArtSQLiteQuery sfQuery(m_sfDB); - if(sfQuery.Init(L"insert or replace into extras (comment,lapid) values (?,?)")) - { - sfQuery.BindValue(strComment); - sfQuery.BindValue(iLapId); - if(!sfQuery.Next() && !sfQuery.IsDone()) - { - DASSERT(FALSE); - } - } -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::SetNetStatus(NETSTATUSSTRING eString, LPCTSTR sz) -{ - AutoLeaveCS _cs(&m_cs); - wcscpy(szLastNetStatus[eString], sz); - m_pUI->NotifyChange(NOTIFY_NEWNETSTATUS,(LPARAM)this); -} -////////////////////////////////////////////////////////////// -void CSQLiteLapDB::NotifyDBArrival(LPCTSTR szPath) -{ - AutoLeaveCS _cs(&m_cs); - wcscpy(szLastNetStatus[NETSTATUS_DB],szPath); - m_pUI->NotifyChange(NOTIFY_NEWDATABASE,(LPARAM)szLastNetStatus[NETSTATUS_DB]); -} -////////////////////////////////////////////////////////////// -LPCTSTR CSQLiteLapDB::GetNetStatus(NETSTATUSSTRING eString) const -{ - return szLastNetStatus[eString]; + return false; +} +////////////////////////////////////////////////////////////// +vector CSQLiteLapDB::GetLaps(int iRaceId) +{ + AutoLeaveCS _cs(&m_cs); + vector lstLaps; + // gotta load all the laps that are in the DB, but we don't want to fully load them, just their laptimes and other directly lap-related data + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"Select laps._id,laps.laptime, laps.unixtime,extras.comment from laps left join extras on extras.lapid = laps._id where laps.raceid=%d", iRaceId); + if(sfQuery.Init(szQuery)) + { + while(sfQuery.Next()) + { + CSQLiteLap* pLap = (CSQLiteLap*)AllocateLap(false); + pLap->Load(m_sfDB,m_rgSF,sfQuery); + if(pLap->IsValid()) + { + lstLaps.push_back(pLap); + } + } + } + return lstLaps; +} + +////////////////////////////////////////////////////////////// +const ILap* CSQLiteLapDB::GetLastLap() { + AutoLeaveCS _cs(&m_cs); + DASSERT(vLastLapId.size() < 2); + if( !vLastLapId.empty() ) { + const int ret = vLastLapId.back(); + vLastLapId.pop_back(); + return GetLap(ret); + } + else + return NULL; +} + +////////////////////////////////////////////////////////////// +const ILap* CSQLiteLapDB::GetLap(int iLapId) +{ + AutoLeaveCS _cs(&m_cs); + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"Select laps._id,laps.laptime, laps.unixtime from laps where laps._id = %d", iLapId); + if(sfQuery.Init(szQuery)) + { + if(sfQuery.Next()) + { + CSQLiteLap* pLap = (CSQLiteLap*)AllocateLap(false); + pLap->Load(m_sfDB,m_rgSF,sfQuery); + + return pLap; + } + } + return NULL; +} +////////////////////////////////////////////////////////////// +const IDataChannel* CSQLiteLapDB::GetDataChannel(int iLapId, DATA_CHANNEL eChannel) const +{ + AutoLeaveCS _cs(&m_cs); + if(eChannel == DATA_CHANNEL_VELOCITY) + { + // since velocity is stored as part of the points table, it is a bit different than the normal data channels + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"select points.time, points.velocity from points where lapid=%d", iLapId); + if(sfQuery.Init(szQuery)) + { + IDataChannel* pChannel = AllocateDataChannel(); + pChannel->Init(iLapId,DATA_CHANNEL_VELOCITY); + while(sfQuery.Next()) + { + int iTime = 0; + double dVel = 0; + if(sfQuery.GetCol(0,&iTime) && sfQuery.GetCol(1,&dVel)) + { + pChannel->AddPoint(iTime, dVel); + } + } + pChannel->Lock(); + return pChannel; + } + } + else + { + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"select channels._id, channels.lapid, channels.channeltype from channels where channels.lapid = %d and channels.channeltype=%d", iLapId, eChannel); + if(sfQuery.Init(szQuery)) + { + if(sfQuery.Next()) + { + IDataChannel* pChannel = AllocateDataChannel(); + pChannel->Load(m_sfDB,sfQuery,true); + // warning: massive memory leaks here + return pChannel; + } + } + } + return NULL; +} +////////////////////////////////////////////////////////////// +set CSQLiteLapDB::GetAvailableChannels(int iLapId) const +{ + AutoLeaveCS _cs(&m_cs); + set setRet; + + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"select channels.channeltype from channels where channels.lapid = %d", iLapId); + if(sfQuery.Init(szQuery)) + { + while(sfQuery.Next()) + { + DATA_CHANNEL eType; + if(sfQuery.GetCol(0,(int*)&eType)) + { + setRet.insert(eType); + } + } + } + return setRet; +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::GetComments(int iLapId, vector& lstComments) const +{ + AutoLeaveCS _cs(&m_cs); + CSfArtSQLiteQuery sfQuery(m_sfDB); + TCHAR szQuery[MAX_PATH]; + _snwprintf(szQuery, NUMCHARS(szQuery), L"select extras.comment from extras where extras.lapid = %d", iLapId); + if(sfQuery.Init(szQuery)) + { + while(sfQuery.Next()) + { + TCHAR szComment[500]; + if(sfQuery.GetCol(0,szComment, NUMCHARS(szComment))) + { + lstComments.push_back(szComment); + } + } + } +} + +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::AddLap(const ILap* pLap, int _iRaceId) +{ + AutoLeaveCS _cs(&m_cs); + vLastLapId.push_back(pLap->GetLapId()); + + CARNUMBERCOMBO sfCarNumber = pLap->GetCarNumbers(); + int iSaveRaceId = -1; + if(mapCarNumberRaceIds.find(sfCarNumber) == mapCarNumberRaceIds.end()) + { + // we've never seen this car number combo before. Time for a new race. + TCHAR szRaceName[200]; + if(sfCarNumber.IsOldVersion()) + { + _snwprintf(szRaceName,NUMCHARS(szRaceName),L"Received from old wifilappers"); + } + else + { + _snwprintf(szRaceName,NUMCHARS(szRaceName),L"Received laps (car %d) - (%d)", sfCarNumber.iCarNumber, sfCarNumber.iSecondaryCarNumber); + } + int iNewRaceId = -1; + if(InitRaceSession(&iNewRaceId,szRaceName)) + { + mapCarNumberRaceIds[sfCarNumber] = iNewRaceId; + iSaveRaceId = iNewRaceId; + } + else + { + return; + } + } + else + { + iSaveRaceId = mapCarNumberRaceIds[sfCarNumber]; + } + + m_setReceivingIds.insert(iSaveRaceId); // this race ID received a lap + m_iLastRaceId = iSaveRaceId; + + m_sfDB.StartTransaction(); + + bool fSuccess = true; + CSfArtSQLiteQuery sfQuery(m_sfDB); + if(sfQuery.Init(L"insert into laps (_id,laptime,unixtime,transmitted,raceid) values (?,?,?,?,?)")) + { + sfQuery.BindValue(pLap->GetLapId()); + sfQuery.BindValue(pLap->GetTime()); + sfQuery.BindValue(pLap->GetStartTime()); + sfQuery.BindValue(0); + sfQuery.BindValue(iSaveRaceId); + if(sfQuery.Next() || sfQuery.IsDone()) + { + // inserted new data, hooray! + + vector lstPoints = pLap->GetPoints(); + for(int x = 0;x < lstPoints.size(); x++) + { + const TimePoint2D& pt = lstPoints[x]; + sfQuery.DeInit(); + if(sfQuery.Init(L"insert into points (x,y,time,velocity,lapid) values (?,?,?,?,?)")) + { + sfQuery.BindValue(pt.flX); + sfQuery.BindValue(pt.flY); + sfQuery.BindValue(pt.iTime); + sfQuery.BindValue(pt.flVelocity); + sfQuery.BindValue(pLap->GetLapId()); + if(!sfQuery.Next() && !sfQuery.IsDone()) + { + fSuccess = false; + break; + } + } + } + } + else + { + fSuccess = false; + } + } + + if(fSuccess) + { + mapLastRaceTimes[iSaveRaceId] = timeGetTime(); + m_pUI->NotifyChange(NOTIFY_NEWLAP,(LPARAM)this); + } + + m_sfDB.StopTransaction(); +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::AddDataChannel(const IDataChannel* pChannel) +{ + AutoLeaveCS _cs(&m_cs); + m_sfDB.StartTransaction(); + + bool fSuccess = true; + CSfArtSQLiteQuery sfQuery(m_sfDB); + if(sfQuery.Init(L"insert into channels (lapid,channeltype) values (?,?)")) + { + sfQuery.BindValue(pChannel->GetLapId()); + sfQuery.BindValue((int)pChannel->GetChannelType()); + if(sfQuery.Next() || sfQuery.IsDone()) + { + // inserted new data, hooray! + long long lastInsert = m_sfDB.GetLastInsertId(); + + + vector lstPoints = pChannel->GetData(); + for(int x = 0;x < lstPoints.size(); x++) + { + const DataPoint& pt = lstPoints[x]; + sfQuery.DeInit(); + if(sfQuery.Init(L"insert into data (time,value,channelid) values (?,?,?)")) + { + sfQuery.BindValue(pt.iTimeMs); + sfQuery.BindValue(pt.flValue); + sfQuery.BindValue(lastInsert); + if(!sfQuery.Next() && !sfQuery.IsDone()) + { + fSuccess = false; + break; + } + } + } + } + else + { + fSuccess = false; + } + } + if(fSuccess) + { + m_pUI->NotifyChange(NOTIFY_NEWDATA,(LPARAM)this); + } + + m_sfDB.StopTransaction(); +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::Clear() +{ +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::AddComment(int iLapId, LPCTSTR strComment) +{ + CSfArtSQLiteQuery sfQuery(m_sfDB); + if(sfQuery.Init(L"insert or replace into extras (comment,lapid) values (?,?)")) + { + sfQuery.BindValue(strComment); + sfQuery.BindValue(iLapId); + if(!sfQuery.Next() && !sfQuery.IsDone()) + { + DASSERT(FALSE); + } + } +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::SetNetStatus(NETSTATUSSTRING eString, LPCTSTR sz) +{ + AutoLeaveCS _cs(&m_cs); + wcscpy(szLastNetStatus[eString], sz); + m_pUI->NotifyChange(NOTIFY_NEWNETSTATUS,(LPARAM)this); +} +////////////////////////////////////////////////////////////// +void CSQLiteLapDB::NotifyDBArrival(LPCTSTR szPath) +{ + AutoLeaveCS _cs(&m_cs); + wcscpy(szLastNetStatus[NETSTATUS_DB],szPath); + m_pUI->NotifyChange(NOTIFY_NEWDATABASE,(LPARAM)szLastNetStatus[NETSTATUS_DB]); +} +////////////////////////////////////////////////////////////// +LPCTSTR CSQLiteLapDB::GetNetStatus(NETSTATUSSTRING eString) const +{ + return szLastNetStatus[eString]; } \ No newline at end of file diff --git a/PitsideConsole/PitsideConsole/SQLiteLapDB.h b/PitsideConsole/PitsideConsole/SQLiteLapDB.h index 0f5c440..e9201b9 100644 --- a/PitsideConsole/PitsideConsole/SQLiteLapDB.h +++ b/PitsideConsole/PitsideConsole/SQLiteLapDB.h @@ -5,6 +5,8 @@ class CSQLiteLapDB : public ILapReceiver { public: + vector vLastLapId; + CSQLiteLapDB(IUI* pUI) : cChannels(0), m_pUI(pUI),m_iLastRaceId(-1) {}; virtual ~CSQLiteLapDB() {}; @@ -26,6 +28,7 @@ class CSQLiteLapDB : public ILapReceiver virtual int GetLapCount(int iRaceId) const override; // gets the lap count for a given race virtual vector GetRaces() override; virtual vector GetLaps(int iRaceId) override; + virtual const ILap* GetLastLap() override; virtual vector GetScoring(int iRaceId) override; virtual bool MergeLaps(int m_iRaceId1, int m_iRaceId2); virtual bool RenameLaps(TCHAR szName[260], int m_RaceId1); diff --git a/PitsideConsole/PitsideConsole/resource.h b/PitsideConsole/PitsideConsole/resource.h index 78767a9..c678c0b 100644 --- a/PitsideConsole/PitsideConsole/resource.h +++ b/PitsideConsole/PitsideConsole/resource.h @@ -4,6 +4,7 @@ #define IDC_DISPLAYTYPE_LINE 4 #define IDC_DISPLAYTYPE_PLOT 5 #define IDC_DISPLAYTYPE_RECEPTION 6 +//#define IDD_DLGSUBDISPLAY 7 // don't use 5-10, we might want more radiobuttons #define IDC_DISPLAYTYPE_LAST 10 @@ -16,7 +17,7 @@ #define IDC_LIVELAPTIME 17 #define IDC_CURRENTREFERENCE 18 #define IDC_CURRENTREMOTEIP 19 -#define IDC_CLEARSELECTION 20 +#define IDC_CLEARCOMMENT 20 #define IDM_OPTIONS 21 #define ID_OPTIONS_KMH 22 #define ID_OPTIONS_MPH 23 @@ -42,7 +43,6 @@ #define ID_OPTIONS_DRAWLINES 43 #define ID_DATA_DASHWARE 44 #define IDC_SPLASHIMAGE 45 -#define IDD_DLGSPLASH 46 #define IDB_SPLASHIMAGE 47 #define ID_DATA_SWITCHSESSION 48 #define ID_OPTIONS_IOIO5VSCALE 49 @@ -65,6 +65,10 @@ #define ID_DATA_EDITSESSION 67 #define IDD_SELECTRACEEDIT 68 #define IDC_RACEEDIT_MERGE 69 +#define ID_OPTIONS_SMOOTH 1000 +#define ID_OPTIONS_XAXIS_KM 1001 +#define ID_OPTIONS_XAXIS_LAT 1002 +#define IDC_LIVEDATA 1003 #define IDC_PLOTTYPE_GRAPH0 70 #define IDC_PLOTTYPE_GRAPH1 72 @@ -258,19 +262,14 @@ #define IDRESET 330 #define IDM_PRINT_BM 331 #define IDM_SAVE_BM 332 -#define IDD_TRACTIONCIRCLE 333 -#define IDC_TRACTIONCIRCLEMAP 334 -#define ID_OPTIONS_TRACTIONCIRCLE 335 +#define IDC_TRACTIONCIRCLEMAP 333 +#define ID_OPTIONS_TRACTIONCIRCLE 334 +#define ID_OPTIONS_CANCELSPLITS 335 + #define IDD_SHOWSECTORS 340 #define IDC_SHOW_SECTORS 341 -#define IDC_SHOW_LAP0 342 -#define IDC_SHOW_LAP1 343 -#define IDC_SHOW_LAP2 344 -#define IDC_SHOW_LAP3 345 -#define IDC_SHOW_LAP4 346 -#define IDC_SHOW_LAP5 347 -#define IDC_SHOW_LAP6 348 -#define IDC_TRACTIONCIRCLEMAP2 349 +#define IDD_DATAVALUES 342 +#define IDC_DATAVALUES 343 #define IDC_PLOTTYPE_TRANS_A0 355 #define IDC_PLOTTYPE_TRANS_A1 356 @@ -360,4 +359,12 @@ #define IDC_PLOTTYPE_LOAD18 458 #define IDC_PLOTTYPE_LOAD19 459 #define IDC_PLOTTYPE_LOAD20 460 + +#define IDD_ALLDATADISPLAY 480 +#define IDC_ALLDATADISPLAY 481 +#define ID_OPTIONS_VERTICAL_LANDSCAPE 482 +#define ID_OPTIONS_VERTICAL_PORTRAIT 483 +#define ID_OPTIONS_FLAT_LANDSCAPE 484 +#define ID_OPTIONS_FLAT_PORTRAIT 485 + // don't put anything below this diff --git a/PitsideConsole/PitsideConsole/settings.txt b/PitsideConsole/PitsideConsole/settings.txt index b02705b..779d5bd 100644 --- a/PitsideConsole/PitsideConsole/settings.txt +++ b/PitsideConsole/PitsideConsole/settings.txt @@ -3,9 +3,13 @@ 1 1 0 +0 +1 order of settings: -whether to run the http server (0 = don't. 1 = do) -http server port (port 80 makes for easiest use. big port numbers like 63938 are less likely to be blocked) -Velocity Units (0 = KMH, 1 = MPH, 2 = M/S) -Draw graph points or lines (0 = points, 1 = lines) --Graph plot color scheme (0 = grey background, 1 = black background) \ No newline at end of file +-Graph plot color scheme (0 = grey background, 1 = black background) +-Smooth accelerometer channels (0 = no smoothing, 1 = smoothing enabled) +-X-Axis display in Latitudinal degrees, or KM (0 = Latitudinal degrees, 1 = KM) diff --git a/PitsideConsole/PitsideConsole/transformations.txt b/PitsideConsole/PitsideConsole/transformations.txt index 2f239df..428751d 100644 --- a/PitsideConsole/PitsideConsole/transformations.txt +++ b/PitsideConsole/PitsideConsole/transformations.txt @@ -3,7 +3,7 @@ P951: Oil Pressure (Bars) 3.26 0.0 0 -P951: Fuel Level % +P951: Fuel Level %% 115.6 -40.1 0.0 @@ -18,18 +18,63 @@ P951: Alternator Voltage 3.57 0.0 0 +P951: Brake Pos %% +0.0 +37.0 +0.0 +0 P951: Tachometer RPM 0.0 31.8 0.0 0 +P924S: Tachometer RPM +0.0 +31.8 +0.0 +0 +P924S: Oil Pressure (Bars) +1.12 +-2.52 +1.41 +0 +P924S: Oil Temp (F) +392.6 +-87.83 +0 +0 +P924S: Fuel Level %% +116 +-49.8 +0.0 +0 +P924S: Coolant T (C) +154.5 +-77.43 +13.0 +0 +P924S: Alternator Voltage +0.0 +5.17 +0.0 +0 +P924S: Brake Pos %% +0.0 +37.0 +0.0 +0 +P924S: Throttle Pos %% +-22.45 +51.0 +0.0 +0 P924: Oil Pressure (Bars) -1.16 +1.16 –2.96 1.84 0 -P924: Gas Tank Reading % -125 +P924: Fuel Level %% +125 -51.8 0.0 0 @@ -43,6 +88,11 @@ P924: Alternator Voltage 5.28 0.0 0 +P924: Brake Pos %% +0.0 +37.0 +0.0 +0 // This file contains quadratic coefficients for transforming raw voltages into meaningful units. You can put up to 100 different transformations into this file for your setup. diff --git a/PitsideConsole/ZLib/.gitignore b/PitsideConsole/ZLib/.gitignore deleted file mode 100644 index 043d84f..0000000 --- a/PitsideConsole/ZLib/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Debug -Release \ No newline at end of file diff --git a/PitsideConsole/ZLib/ReadMe.txt b/PitsideConsole/ZLib/ReadMe.txt deleted file mode 100644 index 693f898..0000000 --- a/PitsideConsole/ZLib/ReadMe.txt +++ /dev/null @@ -1,29 +0,0 @@ -======================================================================== - STATIC LIBRARY : ZLib Project Overview -======================================================================== - -AppWizard has created this ZLib library project for you. - -No source files were created as part of your project. - - -ZLib.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -ZLib.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/PitsideConsole/ZLib/ZLib.vcxproj b/PitsideConsole/ZLib/ZLib.vcxproj deleted file mode 100644 index ff5595f..0000000 --- a/PitsideConsole/ZLib/ZLib.vcxproj +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {08C9BB96-9EF4-4E8B-9227-5AC50E394C7A} - Win32Proj - ZLib - - - - StaticLibrary - true - Unicode - - - StaticLibrary - false - true - Unicode - - - - - - - - - - - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - - - Windows - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreaded - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PitsideConsole/ZLib/ZLib.vcxproj.filters b/PitsideConsole/ZLib/ZLib.vcxproj.filters deleted file mode 100644 index 7f0a7df..0000000 --- a/PitsideConsole/ZLib/ZLib.vcxproj.filters +++ /dev/null @@ -1,105 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/PitsideConsole/ZLib/ZLib.vcxproj.user b/PitsideConsole/ZLib/ZLib.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/PitsideConsole/ZLib/ZLib.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/PitsideConsole/ZLib/adler32.c b/PitsideConsole/ZLib/adler32.c deleted file mode 100644 index a868f07..0000000 --- a/PitsideConsole/ZLib/adler32.c +++ /dev/null @@ -1,179 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#define local static - -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - -#define BASE 65521 /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/PitsideConsole/ZLib/compress.c b/PitsideConsole/ZLib/compress.c deleted file mode 100644 index ea4dfbe..0000000 --- a/PitsideConsole/ZLib/compress.c +++ /dev/null @@ -1,80 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/PitsideConsole/ZLib/crc32.c b/PitsideConsole/ZLib/crc32.c deleted file mode 100644 index 979a719..0000000 --- a/PitsideConsole/ZLib/crc32.c +++ /dev/null @@ -1,425 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Definitions for doing the crc four data bytes at a time. */ -#if !defined(NOBYFOUR) && defined(Z_U4) -# define BYFOUR -#endif -#ifdef BYFOUR - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); - - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local z_crc_t FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - z_crc_t c; - int n, k; - z_crc_t poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0; - for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) - poly |= (z_crc_t)1 << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (z_crc_t)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = ZSWAP32(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = ZSWAP32(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const z_crc_t FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const z_crc_t FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - z_crc_t endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = (z_crc_t)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = ZSWAP32((z_crc_t)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(ZSWAP32(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} - -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} diff --git a/PitsideConsole/ZLib/crc32.h b/PitsideConsole/ZLib/crc32.h deleted file mode 100644 index 9e0c778..0000000 --- a/PitsideConsole/ZLib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const z_crc_t FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/PitsideConsole/ZLib/deflate.c b/PitsideConsole/ZLib/deflate.c deleted file mode 100644 index 9e4c2cb..0000000 --- a/PitsideConsole/ZLib/deflate.c +++ /dev/null @@ -1,1965 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.7 Copyright 1995-2012 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - unsigned char *next; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending (strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - deflate_state *s; - int put; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - Bytef *str; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush)); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if ((long)s->strstart > s->block_start) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/PitsideConsole/ZLib/deflate.h b/PitsideConsole/ZLib/deflate.h deleted file mode 100644 index fbac44d..0000000 --- a/PitsideConsole/ZLib/deflate.h +++ /dev/null @@ -1,346 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2012 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/PitsideConsole/ZLib/gzclose.c b/PitsideConsole/ZLib/gzclose.c deleted file mode 100644 index caeb99a..0000000 --- a/PitsideConsole/ZLib/gzclose.c +++ /dev/null @@ -1,25 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(file) - gzFile file; -{ -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/PitsideConsole/ZLib/gzguts.h b/PitsideConsole/ZLib/gzguts.h deleted file mode 100644 index ee3f281..0000000 --- a/PitsideConsole/ZLib/gzguts.h +++ /dev/null @@ -1,193 +0,0 @@ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif -#endif - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include -#include "zlib.h" -#ifdef STDC -# include -# include -# include -#endif -#include - -#ifdef _WIN32 -# include -#endif - -#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) -# include -#endif - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS -/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 -/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -# ifdef VMS -# define NO_vsnprintf -# endif -# ifdef __OS400__ -# define NO_vsnprintf -# endif -# ifdef __MVS__ -# define NO_vsnprintf -# endif -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -/* gz* functions always use library allocation functions */ -#ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); -#endif - -/* get errno and strerror definition */ -#if defined UNDER_CE -# include -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) -#else -# ifndef NO_STRERROR -# include -# define zstrerror() strerror(errno) -# else -# define zstrerror() "stdio error (consult errno)" -# endif -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); -#endif - -/* default memLevel */ -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* default i/o buffer size -- double this for output when reading */ -#define GZBUFSIZE 8192 - -/* gzip modes, also provide a little integrity check on the passed structure */ -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ - -/* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ - -/* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int how; /* 0: get header, 1: copy, 2: decompress */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ -} gz_state; -typedef gz_state FAR *gz_statep; - -/* shared functions */ -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); -#if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); -#endif - -/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t - value -- needed when comparing unsigned to z_off64_t, which is signed - (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else -unsigned ZLIB_INTERNAL gz_intmax OF((void)); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif diff --git a/PitsideConsole/ZLib/gzlib.c b/PitsideConsole/ZLib/gzlib.c deleted file mode 100644 index ca55c6e..0000000 --- a/PitsideConsole/ZLib/gzlib.c +++ /dev/null @@ -1,620 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004, 2010, 2011, 2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(_WIN32) && !defined(__BORLANDC__) -# define LSEEK _lseeki64 -#else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif -#endif - -/* Local functions */ -local void gz_reset OF((gz_statep)); -local gzFile gz_open OF((const void *, int, const char *)); - -#if defined UNDER_CE - -/* Map the Windows error number in ERROR to a locale-dependent error message - string and return a pointer to it. Typically, the values for ERROR come - from GetLastError. - - The string pointed to shall not be modified by the application, but may be - overwritten by a subsequent call to gz_strwinerror - - The gz_strwinerror function does not change the current setting of - GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror (error) - DWORD error; -{ - static char buf[1024]; - - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } - - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } - - wcstombs(buf, msgbuf, chars + 1); - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } - - SetLastError(lasterr); - return buf; -} - -#endif /* UNDER_CE */ - -/* Reset gzip file state */ -local void gz_reset(state) - gz_statep state; -{ - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - } - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(path, fd, mode) - const void *path; - int fd; - const char *mode; -{ - gz_statep state; - size_t len; - int oflag; -#ifdef O_CLOEXEC - int cloexec = 0; -#endif -#ifdef O_EXCL - int exclusive = 0; -#endif - - /* check input */ - if (path == NULL) - return NULL; - - /* allocate gzFile structure to return */ - state = malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; -#ifdef O_CLOEXEC - case 'e': - cloexec = 1; - break; -#endif -#ifdef O_EXCL - case 'x': - exclusive = 1; - break; -#endif - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - case 'T': - state->direct = 1; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); - return NULL; - } - state->direct = 1; /* for empty file */ - } - - /* save the path name for error messages */ -#ifdef _WIN32 - if (fd == -2) { - len = wcstombs(NULL, path, 0); - if (len == (size_t)-1) - len = 0; - } - else -#endif - len = strlen(path); - state->path = malloc(len + 1); - if (state->path == NULL) { - free(state); - return NULL; - } -#ifdef _WIN32 - if (fd == -2) - if (len) - wcstombs(state->path, path, len + 1); - else - *(state->path) = 0; - else -#endif - strcpy(state->path, path); - - /* compute the flags for open() */ - oflag = -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif -#ifdef O_CLOEXEC - (cloexec ? O_CLOEXEC : 0) | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | -#ifdef O_EXCL - (exclusive ? O_EXCL : 0) | -#endif - (state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))); - - /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( -#ifdef _WIN32 - fd == -2 ? _wopen(path, oflag, 0666) : -#endif - open(path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) - state->mode = GZ_WRITE; /* simplify later checks */ - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; -{ - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; - sprintf(path, "", fd); /* for debugging */ - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -#ifdef _WIN32 -gzFile ZEXPORT gzopen_w(path, mode) - const wchar_t *path; - const char *mode; -{ - return gz_open(path, -2, mode); -} -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if (size < 2) - size = 2; /* need two bytes to check magic header */ - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; -{ - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->x.pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(file) - gzFile file; -{ - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(file) - gzFile file; -{ - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(file) - gzFile file; -{ - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->msg == NULL ? "" : state->msg; -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; -{ - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, save as static string */ - if (err == Z_MEM_ERROR) { - state->msg = (char *)msg; - return; - } - - /* construct error message with path */ - if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { - state->err = Z_MEM_ERROR; - state->msg = (char *)"out of memory"; - return; - } - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); - return; -} - -#ifndef INT_MAX -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() -{ - unsigned p, q; - - p = 1; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -} -#endif diff --git a/PitsideConsole/ZLib/gzread.c b/PitsideConsole/ZLib/gzread.c deleted file mode 100644 index 3493d34..0000000 --- a/PitsideConsole/ZLib/gzread.c +++ /dev/null @@ -1,589 +0,0 @@ -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); -local int gz_avail OF((gz_statep)); -local int gz_look OF((gz_statep)); -local int gz_decomp OF((gz_statep)); -local int gz_fetch OF((gz_statep)); -local int gz_skip OF((gz_statep, z_off64_t)); - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; -{ - int ret; - - *have = 0; - do { - ret = read(state->fd, buf + *have, len - *have); - if (ret <= 0) - break; - *have += ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - If strm->avail_in != 0, then the current data is moved to the beginning of - the input buffer, and then the remainder of the buffer is loaded with the - available data from the input file. */ -local int gz_avail(state) - gz_statep state; -{ - unsigned got; - z_streamp strm = &(state->strm); - - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in, *q = strm->next_in; - unsigned n = strm->avail_in; - do { - *p++ = *q++; - } while (--n); - } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression. If direct copying, then leftover input - data from the input buffer will be copied to the output buffer. In that - case, all further file reads will be directly to either the output buffer or - a user buffer. If decompressing, the inflate state will be initialized. - gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = malloc(state->want); - state->out = malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is - a logical dilemma here when considering the case of a partially written - gzip file, to wit, if a single 31 byte is written, then we cannot tell - whether this is a single-byte file, or just a partially written gzip - file -- for here we assume that if a gzip file is being written, then - the header will be written in a single operation, so that reading a - single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { - inflateReset(strm); - state->how = GZIP; - state->direct = 0; - return 0; - } - - /* no gzip header -- if we were decoding gzip before, then this is trailing - garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; - return 0; - } - - /* doing raw i/o, copy any leftover input to output -- this assumes that - the output buffer is larger than the input buffer, which also assures - space for gzungetc() */ - state->x.next = state->out; - if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - } - state->how = COPY; - state->direct = 1; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. */ -local int gz_decomp(state) - gz_statep state; -{ - int ret = Z_OK; - unsigned had; - z_streamp strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; - - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) - state->how = LOOK; - - /* good decompression */ - return 0; -} - -/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for to determine whether to copy or decompress. Returns -1 on error, - otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the - end of the input file has been reached and all data has been processed. */ -local int gz_fetch(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - do { - switch(state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; -} - -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(state, len) - gz_statep state; - z_off64_t len; -{ - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - len -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - unsigned got, n; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return -1; - } - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* first just try copying data from the output buffer */ - if (state->x.have) { - n = state->x.have > len ? len : state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) { - state->past = 1; /* tried to read past end */ - break; - } - - /* need output data -- for small len or new stream load up our output - buffer */ - else if (state->how == LOOK || len < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - continue; /* no progress yet -- go back to copy above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } - - /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, buf, len, &n) == -1) - return -1; - } - - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - strm->avail_out = len; - strm->next_out = buf; - if (gz_decomp(state) == -1) - return -1; - n = state->x.have; - state->x.have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len); - - /* return number of bytes read into user buffer (will fit in int) */ - return (int)got; -} - -/* -- see zlib.h -- */ -#undef gzgetc -int ZEXPORT gzgetc(file) - gzFile file; -{ - int ret; - unsigned char buf[1]; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } - - /* nothing there -- try gzread() */ - ret = gzread(file, buf, 1); - return ret < 1 ? -1 : buf[0]; -} - -int ZEXPORT gzgetc_(file) -gzFile file; -{ - return gzgetc(file); -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } - - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* return terminated string, or if nothing, end of file */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(file) - gzFile file; -{ - int ret, err; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; -} diff --git a/PitsideConsole/ZLib/gzwrite.c b/PitsideConsole/ZLib/gzwrite.c deleted file mode 100644 index 27cb342..0000000 --- a/PitsideConsole/ZLib/gzwrite.c +++ /dev/null @@ -1,565 +0,0 @@ -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_init OF((gz_statep)); -local int gz_comp OF((gz_statep, int)); -local int gz_zero OF((gz_statep, z_off64_t)); - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on failure or 0 on success. */ -local int gz_init(state) - gz_statep state; -{ - int ret; - z_streamp strm = &(state->strm); - - /* allocate input buffer */ - state->in = malloc(state->want); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file, otherwise 0. - flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, - then the deflate() state is reset to start a new gzip stream. If gz->direct - is true, then simply write to the output file without compressing, and - ignore flush. */ -local int gz_comp(state, flush) - gz_statep state; - int flush; -{ - int ret, got; - unsigned have; - z_streamp strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* write directly if requested */ - if (state->direct) { - got = write(state->fd, strm->next_in, strm->avail_in); - if (got < 0 || (unsigned)got != strm->avail_in) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in = 0; - return 0; - } - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - have = (unsigned)(strm->next_out - state->x.next); - if (have && ((got = write(state->fd, state->x.next, have)) < 0 || - (unsigned)got != have)) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - } - state->x.next = strm->next_out; - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - deflateReset(strm); - - /* all done, no errors */ - return 0; -} - -/* Compress len zeros to output. Return -1 on error, 0 on success. */ -local int gz_zero(state, len) - gz_statep state; - z_off64_t len; -{ - int first; - unsigned n; - z_streamp strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - unsigned put = len; - unsigned n; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - if (strm->avail_in == 0) - strm->next_in = state->in; - n = state->size - strm->avail_in; - if (n > len) - n = len; - memcpy(strm->next_in + strm->avail_in, buf, n); - strm->avail_in += n; - state->x.pos += n; - buf = (char *)buf + n; - len -= n; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } - else { - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - strm->avail_in = len; - strm->next_in = (voidp)buf; - state->x.pos += len; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } - - /* input was all buffered or compressed (put will fit in int) */ - return (int)put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned char buf[1]; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (strm->avail_in < state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - strm->next_in[strm->avail_in++] = c; - state->x.pos++; - return c & 0xff; - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = c; - if (gzwrite(file, buf, 1) != 1) - return -1; - return c & 0xff; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(file, str) - gzFile file; - const char *str; -{ - int ret; - unsigned len; - - /* write string */ - len = (unsigned)strlen(str); - ret = gzwrite(file, str, len); - return ret == 0 && len != 0 ? -1 : ret; -} - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -#include - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) -{ - int size, len; - gz_statep state; - z_streamp strm; - va_list va; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; - va_start(va, format); -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf((char *)(state->in), format, va); - va_end(va); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; -# else - len = vsprintf((char *)(state->in), format, va); - va_end(va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf((char *)(state->in), size, format, va); - va_end(va); - len = strlen((char *)(state->in)); -# else - len = vsnprintf((char *)(state->in), size, format, va); - va_end(va); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) - return 0; - - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; - return len; -} - -#else /* !STDC && !Z_HAVE_STDARG_H */ - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - int size, len; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that can really pass pointer in ints */ - if (sizeof(int) != sizeof(void *)) - return 0; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; -# else - len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen((char *)(state->in)); -# else - len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, - a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, - a19, a20); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) - return 0; - - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; - return len; -} - -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* compress remaining data with requested flush */ - gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(file) - gzFile file; -{ - int ret = Z_OK; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } - - /* flush, free memory, and close file */ - if (state->size) { - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; -} diff --git a/PitsideConsole/ZLib/infback.c b/PitsideConsole/ZLib/infback.c deleted file mode 100644 index 981aff1..0000000 --- a/PitsideConsole/ZLib/infback.c +++ /dev/null @@ -1,640 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/PitsideConsole/ZLib/inffast.c b/PitsideConsole/ZLib/inffast.c deleted file mode 100644 index 2f1d60b..0000000 --- a/PitsideConsole/ZLib/inffast.c +++ /dev/null @@ -1,340 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - PUP(out) = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - PUP(out) = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - PUP(out) = PUP(from); - } while (--len); - continue; - } -#endif - } - from = window - OFF; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/PitsideConsole/ZLib/inffast.h b/PitsideConsole/ZLib/inffast.h deleted file mode 100644 index e5c1aa4..0000000 --- a/PitsideConsole/ZLib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/PitsideConsole/ZLib/inffixed.h b/PitsideConsole/ZLib/inffixed.h deleted file mode 100644 index d628327..0000000 --- a/PitsideConsole/ZLib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/PitsideConsole/ZLib/inflate.c b/PitsideConsole/ZLib/inflate.c deleted file mode 100644 index 47418a1..0000000 --- a/PitsideConsole/ZLib/inflate.c +++ /dev/null @@ -1,1496 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->window = Z_NULL; - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - else if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long dictid; - unsigned char *next; - unsigned avail; - int ret; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - next = strm->next_out; - avail = strm->avail_out; - strm->next_out = (Bytef *)dictionary + dictLength; - strm->avail_out = 0; - ret = updatewindow(strm, dictLength); - strm->avail_out = avail; - strm->next_out = next; - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->sane = !subvert; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - return Z_OK; -#else - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; - state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} diff --git a/PitsideConsole/ZLib/inflate.h b/PitsideConsole/ZLib/inflate.h deleted file mode 100644 index 95f4986..0000000 --- a/PitsideConsole/ZLib/inflate.h +++ /dev/null @@ -1,122 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2009 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 10K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/PitsideConsole/ZLib/inftrees.c b/PitsideConsole/ZLib/inftrees.c deleted file mode 100644 index abcd7c4..0000000 --- a/PitsideConsole/ZLib/inftrees.c +++ /dev/null @@ -1,306 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.7 Copyright 1995-2012 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 78, 68}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/PitsideConsole/ZLib/inftrees.h b/PitsideConsole/ZLib/inftrees.h deleted file mode 100644 index baa53a0..0000000 --- a/PitsideConsole/ZLib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/PitsideConsole/ZLib/test.h b/PitsideConsole/ZLib/test.h deleted file mode 100644 index e69de29..0000000 diff --git a/PitsideConsole/ZLib/trees.c b/PitsideConsole/ZLib/trees.c deleted file mode 100644 index 8c32b21..0000000 --- a/PitsideConsole/ZLib/trees.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2012 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; -{ - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/PitsideConsole/ZLib/trees.h b/PitsideConsole/ZLib/trees.h deleted file mode 100644 index d35639d..0000000 --- a/PitsideConsole/ZLib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/PitsideConsole/ZLib/uncompr.c b/PitsideConsole/ZLib/uncompr.c deleted file mode 100644 index ad98be3..0000000 --- a/PitsideConsole/ZLib/uncompr.c +++ /dev/null @@ -1,59 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} diff --git a/PitsideConsole/ZLib/zconf.h b/PitsideConsole/ZLib/zconf.h deleted file mode 100644 index 8a46a58..0000000 --- a/PitsideConsole/ZLib/zconf.h +++ /dev/null @@ -1,506 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2012 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetHeader z_inflateGetHeader -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -/* ./configure may #define Z_U4 here */ - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# else -# if (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# else -# if (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -# endif -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#ifdef _WIN32 -# include /* for wchar_t */ -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/PitsideConsole/ZLib/zlib.h b/PitsideConsole/ZLib/zlib.h deleted file mode 100644 index 3edf3ac..0000000 --- a/PitsideConsole/ZLib/zlib.h +++ /dev/null @@ -1,1744 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.7, May 2nd, 2012 - - Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.7" -#define ZLIB_VERNUM 0x1270 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 7 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). Then deflate is guaranteed to - return Z_STREAM_END. If not enough output space is provided, deflate will - not return Z_STREAM_END, and it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - producted so far. The CRC-32 is checked against the gzip trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above or -1 << 16 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - -#endif /* !Z_SOLO */ - -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; -#endif - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/PitsideConsole/ZLib/zutil.c b/PitsideConsole/ZLib/zutil.c deleted file mode 100644 index 65e0d3b..0000000 --- a/PitsideConsole/ZLib/zutil.c +++ /dev/null @@ -1,324 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifndef Z_SOLO -# include "gzguts.h" -#endif - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ diff --git a/PitsideConsole/ZLib/zutil.h b/PitsideConsole/ZLib/zutil.h deleted file mode 100644 index 4e3dcc6..0000000 --- a/PitsideConsole/ZLib/zutil.h +++ /dev/null @@ -1,252 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2012 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif - -#ifdef Z_SOLO - typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - -#if defined(__BORLANDC__) && !defined(MSDOS) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -#ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); -#endif - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value */ -#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -#endif /* ZUTIL_H */ diff --git a/TestApp/TestApp.iml b/TestApp/TestApp.iml new file mode 100644 index 0000000..9c8070b --- /dev/null +++ b/TestApp/TestApp.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/WifiLapperFull/.idea/.name b/WifiLapperFull/.idea/.name new file mode 100644 index 0000000..504422c --- /dev/null +++ b/WifiLapperFull/.idea/.name @@ -0,0 +1 @@ +WifiLapperFull \ No newline at end of file diff --git a/WifiLapperFull/.idea/WifiLapperFull.iml b/WifiLapperFull/.idea/WifiLapperFull.iml new file mode 100644 index 0000000..ccf83c5 --- /dev/null +++ b/WifiLapperFull/.idea/WifiLapperFull.iml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/WifiLapperFull/.idea/compiler.xml b/WifiLapperFull/.idea/compiler.xml new file mode 100644 index 0000000..28bb10a --- /dev/null +++ b/WifiLapperFull/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/WifiLapperFull/.idea/copyright/profiles_settings.xml b/WifiLapperFull/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..c7d1c5a --- /dev/null +++ b/WifiLapperFull/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/WifiLapperFull/.idea/encodings.xml b/WifiLapperFull/.idea/encodings.xml new file mode 100644 index 0000000..7c62b52 --- /dev/null +++ b/WifiLapperFull/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/WifiLapperFull/.idea/misc.xml b/WifiLapperFull/.idea/misc.xml new file mode 100644 index 0000000..3c43605 --- /dev/null +++ b/WifiLapperFull/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/WifiLapperFull/.idea/modules.xml b/WifiLapperFull/.idea/modules.xml new file mode 100644 index 0000000..d72fddb --- /dev/null +++ b/WifiLapperFull/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/WifiLapperFull/.idea/scopes/scope_settings.xml b/WifiLapperFull/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..0d5175c --- /dev/null +++ b/WifiLapperFull/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/WifiLapperFull/.idea/vcs.xml b/WifiLapperFull/.idea/vcs.xml new file mode 100644 index 0000000..d2d96f2 --- /dev/null +++ b/WifiLapperFull/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/WifiLapperFull/.idea/workspace.xml b/WifiLapperFull/.idea/workspace.xml new file mode 100644 index 0000000..692f762 --- /dev/null +++ b/WifiLapperFull/.idea/workspace.xml @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + + + 1423903845224 + 1423903845224 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No facets are configured + + + + + + + + + + + + + + + 1.8 + + + + + + + + WifiLapperFull + + + + + + + + + + + + + + + + diff --git a/WifiLapperFull/WifiLapperFull.iml b/WifiLapperFull/WifiLapperFull.iml new file mode 100644 index 0000000..cfbf8b7 --- /dev/null +++ b/WifiLapperFull/WifiLapperFull.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/WifiLapperLite/WifiLapperLite.iml b/WifiLapperLite/WifiLapperLite.iml new file mode 100644 index 0000000..cfbf8b7 --- /dev/null +++ b/WifiLapperLite/WifiLapperLite.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/WifiLapperTablet/WifiLapperTablet.iml b/WifiLapperTablet/WifiLapperTablet.iml new file mode 100644 index 0000000..cfbf8b7 --- /dev/null +++ b/WifiLapperTablet/WifiLapperTablet.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/out/production/IOIOLib/ioio/lib/BuildConfig.class b/out/production/IOIOLib/ioio/lib/BuildConfig.class new file mode 100644 index 0000000..e307f5b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/BuildConfig.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/AnalogInput.class b/out/production/IOIOLib/ioio/lib/api/AnalogInput.class new file mode 100644 index 0000000..c780592 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/AnalogInput.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/Closeable.class b/out/production/IOIOLib/ioio/lib/api/Closeable.class new file mode 100644 index 0000000..ac7d213 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/Closeable.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/DigitalInput$Spec$Mode.class b/out/production/IOIOLib/ioio/lib/api/DigitalInput$Spec$Mode.class new file mode 100644 index 0000000..6b66d97 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/DigitalInput$Spec$Mode.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/DigitalInput$Spec.class b/out/production/IOIOLib/ioio/lib/api/DigitalInput$Spec.class new file mode 100644 index 0000000..80ffbc9 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/DigitalInput$Spec.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/DigitalInput.class b/out/production/IOIOLib/ioio/lib/api/DigitalInput.class new file mode 100644 index 0000000..f3f7462 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/DigitalInput.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/DigitalOutput$Spec$Mode.class b/out/production/IOIOLib/ioio/lib/api/DigitalOutput$Spec$Mode.class new file mode 100644 index 0000000..59c486b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/DigitalOutput$Spec$Mode.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/DigitalOutput$Spec.class b/out/production/IOIOLib/ioio/lib/api/DigitalOutput$Spec.class new file mode 100644 index 0000000..45daf97 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/DigitalOutput$Spec.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/DigitalOutput.class b/out/production/IOIOLib/ioio/lib/api/DigitalOutput.class new file mode 100644 index 0000000..593bc14 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/DigitalOutput.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/IOIO$VersionType.class b/out/production/IOIOLib/ioio/lib/api/IOIO$VersionType.class new file mode 100644 index 0000000..9dacbf7 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/IOIO$VersionType.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/IOIO.class b/out/production/IOIOLib/ioio/lib/api/IOIO.class new file mode 100644 index 0000000..2695d74 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/IOIO.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/IOIOConnection.class b/out/production/IOIOLib/ioio/lib/api/IOIOConnection.class new file mode 100644 index 0000000..30a4320 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/IOIOConnection.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/IOIOFactory.class b/out/production/IOIOLib/ioio/lib/api/IOIOFactory.class new file mode 100644 index 0000000..7f691f2 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/IOIOFactory.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/IcspMaster.class b/out/production/IOIOLib/ioio/lib/api/IcspMaster.class new file mode 100644 index 0000000..7c3ad9b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/IcspMaster.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/PulseInput$ClockRate.class b/out/production/IOIOLib/ioio/lib/api/PulseInput$ClockRate.class new file mode 100644 index 0000000..058bf75 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/PulseInput$ClockRate.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/PulseInput$PulseMode.class b/out/production/IOIOLib/ioio/lib/api/PulseInput$PulseMode.class new file mode 100644 index 0000000..1fc53f8 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/PulseInput$PulseMode.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/PulseInput.class b/out/production/IOIOLib/ioio/lib/api/PulseInput.class new file mode 100644 index 0000000..59ebb85 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/PulseInput.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/PwmOutput.class b/out/production/IOIOLib/ioio/lib/api/PwmOutput.class new file mode 100644 index 0000000..65e5974 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/PwmOutput.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/SpiMaster$Config.class b/out/production/IOIOLib/ioio/lib/api/SpiMaster$Config.class new file mode 100644 index 0000000..a50ba10 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/SpiMaster$Config.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/SpiMaster$Rate.class b/out/production/IOIOLib/ioio/lib/api/SpiMaster$Rate.class new file mode 100644 index 0000000..184dd70 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/SpiMaster$Rate.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/SpiMaster$Result.class b/out/production/IOIOLib/ioio/lib/api/SpiMaster$Result.class new file mode 100644 index 0000000..a31ec84 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/SpiMaster$Result.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/SpiMaster.class b/out/production/IOIOLib/ioio/lib/api/SpiMaster.class new file mode 100644 index 0000000..dff173a Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/SpiMaster.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/TwiMaster$Rate.class b/out/production/IOIOLib/ioio/lib/api/TwiMaster$Rate.class new file mode 100644 index 0000000..6a9403f Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/TwiMaster$Rate.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/TwiMaster$Result.class b/out/production/IOIOLib/ioio/lib/api/TwiMaster$Result.class new file mode 100644 index 0000000..a52ea0e Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/TwiMaster$Result.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/TwiMaster.class b/out/production/IOIOLib/ioio/lib/api/TwiMaster.class new file mode 100644 index 0000000..7429120 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/TwiMaster.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/Uart$Parity.class b/out/production/IOIOLib/ioio/lib/api/Uart$Parity.class new file mode 100644 index 0000000..0542d3d Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/Uart$Parity.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/Uart$StopBits.class b/out/production/IOIOLib/ioio/lib/api/Uart$StopBits.class new file mode 100644 index 0000000..05df6fe Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/Uart$StopBits.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/Uart.class b/out/production/IOIOLib/ioio/lib/api/Uart.class new file mode 100644 index 0000000..5006f06 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/Uart.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/exception/ConnectionLostException.class b/out/production/IOIOLib/ioio/lib/api/exception/ConnectionLostException.class new file mode 100644 index 0000000..1feb41b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/exception/ConnectionLostException.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/exception/IncompatibilityException.class b/out/production/IOIOLib/ioio/lib/api/exception/IncompatibilityException.class new file mode 100644 index 0000000..6e00dc9 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/exception/IncompatibilityException.class differ diff --git a/out/production/IOIOLib/ioio/lib/api/exception/OutOfResourceException.class b/out/production/IOIOLib/ioio/lib/api/exception/OutOfResourceException.class new file mode 100644 index 0000000..9c4cef7 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/api/exception/OutOfResourceException.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/AbstractPin.class b/out/production/IOIOLib/ioio/lib/impl/AbstractPin.class new file mode 100644 index 0000000..4c4604e Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/AbstractPin.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/AbstractResource$State.class b/out/production/IOIOLib/ioio/lib/impl/AbstractResource$State.class new file mode 100644 index 0000000..665ea1b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/AbstractResource$State.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/AbstractResource.class b/out/production/IOIOLib/ioio/lib/impl/AbstractResource.class new file mode 100644 index 0000000..c3f6784 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/AbstractResource.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/AnalogInputImpl.class b/out/production/IOIOLib/ioio/lib/impl/AnalogInputImpl.class new file mode 100644 index 0000000..1b92277 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/AnalogInputImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/Constants.class b/out/production/IOIOLib/ioio/lib/impl/Constants.class new file mode 100644 index 0000000..491f29b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/Constants.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/DigitalInputImpl.class b/out/production/IOIOLib/ioio/lib/impl/DigitalInputImpl.class new file mode 100644 index 0000000..ac256a8 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/DigitalInputImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/DigitalOutputImpl.class b/out/production/IOIOLib/ioio/lib/impl/DigitalOutputImpl.class new file mode 100644 index 0000000..aff801b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/DigitalOutputImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream$FlushThread.class b/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream$FlushThread.class new file mode 100644 index 0000000..87a21d2 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream$FlushThread.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream$Sender.class b/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream$Sender.class new file mode 100644 index 0000000..8f165a9 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream$Sender.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream.class b/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream.class new file mode 100644 index 0000000..bad1e1a Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/FlowControlledOutputStream.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$FlushThread.class b/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$FlushThread.class new file mode 100644 index 0000000..35a937b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$FlushThread.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$Packet.class b/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$Packet.class new file mode 100644 index 0000000..9a02397 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$Packet.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$Sender.class b/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$Sender.class new file mode 100644 index 0000000..f469339 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender$Sender.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender.class b/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender.class new file mode 100644 index 0000000..823fe71 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/FlowControlledPacketSender.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IOIOImpl$1.class b/out/production/IOIOLib/ioio/lib/impl/IOIOImpl$1.class new file mode 100644 index 0000000..0ee1f0b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IOIOImpl$1.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IOIOImpl$State.class b/out/production/IOIOLib/ioio/lib/impl/IOIOImpl$State.class new file mode 100644 index 0000000..c7500ad Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IOIOImpl$State.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IOIOImpl.class b/out/production/IOIOLib/ioio/lib/impl/IOIOImpl.class new file mode 100644 index 0000000..188d913 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IOIOImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$IncomingHandler.class b/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$IncomingHandler.class new file mode 100644 index 0000000..29279a0 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$IncomingHandler.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$IncomingThread.class b/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$IncomingThread.class new file mode 100644 index 0000000..04d31f3 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$IncomingThread.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$PwmScale.class b/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$PwmScale.class new file mode 100644 index 0000000..00ae64f Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol$PwmScale.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol.class b/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol.class new file mode 100644 index 0000000..56f76e5 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IOIOProtocol.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IcspMasterImpl.class b/out/production/IOIOLib/ioio/lib/impl/IcspMasterImpl.class new file mode 100644 index 0000000..0315429 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IcspMasterImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IncapImpl.class b/out/production/IOIOLib/ioio/lib/impl/IncapImpl.class new file mode 100644 index 0000000..4c70cfa Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IncapImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IncomingState$ConnectionState.class b/out/production/IOIOLib/ioio/lib/impl/IncomingState$ConnectionState.class new file mode 100644 index 0000000..57c892b Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IncomingState$ConnectionState.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IncomingState$DataModuleListener.class b/out/production/IOIOLib/ioio/lib/impl/IncomingState$DataModuleListener.class new file mode 100644 index 0000000..97f293f Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IncomingState$DataModuleListener.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IncomingState$DataModuleState.class b/out/production/IOIOLib/ioio/lib/impl/IncomingState$DataModuleState.class new file mode 100644 index 0000000..139d610 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IncomingState$DataModuleState.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IncomingState$DisconnectListener.class b/out/production/IOIOLib/ioio/lib/impl/IncomingState$DisconnectListener.class new file mode 100644 index 0000000..7c7cf08 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IncomingState$DisconnectListener.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IncomingState$InputPinListener.class b/out/production/IOIOLib/ioio/lib/impl/IncomingState$InputPinListener.class new file mode 100644 index 0000000..de4b5bf Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IncomingState$InputPinListener.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IncomingState$InputPinState.class b/out/production/IOIOLib/ioio/lib/impl/IncomingState$InputPinState.class new file mode 100644 index 0000000..0bc3cc3 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IncomingState$InputPinState.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/IncomingState.class b/out/production/IOIOLib/ioio/lib/impl/IncomingState.class new file mode 100644 index 0000000..e9634d8 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/IncomingState.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/ModuleAllocator.class b/out/production/IOIOLib/ioio/lib/impl/ModuleAllocator.class new file mode 100644 index 0000000..658e0f0 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/ModuleAllocator.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/PinFunctionMap.class b/out/production/IOIOLib/ioio/lib/impl/PinFunctionMap.class new file mode 100644 index 0000000..3e72b53 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/PinFunctionMap.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/PwmImpl.class b/out/production/IOIOLib/ioio/lib/impl/PwmImpl.class new file mode 100644 index 0000000..86b2afb Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/PwmImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/QueueInputStream.class b/out/production/IOIOLib/ioio/lib/impl/QueueInputStream.class new file mode 100644 index 0000000..d6ed1d6 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/QueueInputStream.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/SocketIOIOConnection.class b/out/production/IOIOLib/ioio/lib/impl/SocketIOIOConnection.class new file mode 100644 index 0000000..a1b4090 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/SocketIOIOConnection.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl$OutgoingPacket.class b/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl$OutgoingPacket.class new file mode 100644 index 0000000..65a4d30 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl$OutgoingPacket.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl$SpiResult.class b/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl$SpiResult.class new file mode 100644 index 0000000..3b80384 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl$SpiResult.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl.class b/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl.class new file mode 100644 index 0000000..bcb182d Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/SpiMasterImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl$OutgoingPacket.class b/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl$OutgoingPacket.class new file mode 100644 index 0000000..a258559 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl$OutgoingPacket.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl$TwiResult.class b/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl$TwiResult.class new file mode 100644 index 0000000..d43266c Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl$TwiResult.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl.class b/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl.class new file mode 100644 index 0000000..43a9f07 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/TwiMasterImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/impl/UartImpl.class b/out/production/IOIOLib/ioio/lib/impl/UartImpl.class new file mode 100644 index 0000000..19fda39 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/impl/UartImpl.class differ diff --git a/out/production/IOIOLib/ioio/lib/util/AbstractIOIOActivity$IOIOThread.class b/out/production/IOIOLib/ioio/lib/util/AbstractIOIOActivity$IOIOThread.class new file mode 100644 index 0000000..534264e Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/util/AbstractIOIOActivity$IOIOThread.class differ diff --git a/out/production/IOIOLib/ioio/lib/util/AbstractIOIOActivity.class b/out/production/IOIOLib/ioio/lib/util/AbstractIOIOActivity.class new file mode 100644 index 0000000..e78a046 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/util/AbstractIOIOActivity.class differ diff --git a/out/production/IOIOLib/ioio/lib/util/IOIOConnectionDiscovery$IOIOConnectionSpec.class b/out/production/IOIOLib/ioio/lib/util/IOIOConnectionDiscovery$IOIOConnectionSpec.class new file mode 100644 index 0000000..ef84de3 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/util/IOIOConnectionDiscovery$IOIOConnectionSpec.class differ diff --git a/out/production/IOIOLib/ioio/lib/util/IOIOConnectionDiscovery.class b/out/production/IOIOLib/ioio/lib/util/IOIOConnectionDiscovery.class new file mode 100644 index 0000000..54c4bff Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/util/IOIOConnectionDiscovery.class differ diff --git a/out/production/IOIOLib/ioio/lib/util/SocketIOIOConnectionDiscovery.class b/out/production/IOIOLib/ioio/lib/util/SocketIOIOConnectionDiscovery.class new file mode 100644 index 0000000..f187532 Binary files /dev/null and b/out/production/IOIOLib/ioio/lib/util/SocketIOIOConnectionDiscovery.class differ