/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : ChunkView * * * * $Archive:: /Commando/Code/Tools/ChunkView/ChunkDataView.cpp $* * * * Author:: Greg Hjelstrom * * * * $Modtime:: 9/28/99 9:48a $* * * * $Revision:: 2 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ // ChunkDataView.cpp : implementation file // #include "stdafx.h" #include "ChunkView.h" #include "ChunkDataView.h" #include "ChunkViewDoc.h" #include "ChunkFileImage.h" #include "HexToString.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CChunkDataView IMPLEMENT_DYNCREATE(CChunkDataView, CListView) CChunkDataView::CChunkDataView() : WordSize(WORD_SIZE_BYTE), DisplayMode(DISPLAY_MODE_HEX) { } CChunkDataView::~CChunkDataView() { } BEGIN_MESSAGE_MAP(CChunkDataView, CListView) //{{AFX_MSG_MAP(CChunkDataView) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChunkDataView drawing void CChunkDataView::OnDraw(CDC* pDC) { CDocument* pDoc = GetDocument(); // TODO: add draw code here } ///////////////////////////////////////////////////////////////////////////// // CChunkDataView diagnostics #ifdef _DEBUG void CChunkDataView::AssertValid() const { CListView::AssertValid(); } void CChunkDataView::Dump(CDumpContext& dc) const { CListView::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CChunkDataView message handlers void CChunkDataView::OnInitialUpdate() { CListView::OnInitialUpdate(); CListCtrl &list = GetListCtrl(); long flags = list.GetStyle(); flags |= LVS_REPORT; SetWindowLong(list.GetSafeHwnd(), GWL_STYLE, flags); //list.SetFont (); ::SendMessage (list, WM_SETFONT, (WPARAM)GetStockObject (ANSI_FIXED_FONT), 0L); } void CChunkDataView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { if (this == pSender) return; // Get the document and currently selected chunk CListCtrl &list = GetListCtrl(); CChunkViewDoc * doc= (CChunkViewDoc *)GetDocument(); const ChunkImageClass * chunk = doc->Get_Cur_Chunk(); // Reset the list list.DeleteAllItems(); // Rebuild the list view if (chunk != NULL) { Display_Chunk(chunk); } } void CChunkDataView::Display_Chunk(const ChunkImageClass * chunk) { CListCtrl &list = GetListCtrl(); CChunkViewDoc * doc= (CChunkViewDoc *)GetDocument(); if (chunk->Get_Data() == NULL) { Display_Chunk_Sub_Chunks(chunk); } else { switch (DisplayMode) { case DISPLAY_MODE_HEX: Display_Chunk_Hex(chunk); break; case DISPLAY_MODE_MICROCHUNKS: Display_Chunk_Micro_Chunks(chunk); break; }; } } void CChunkDataView::Display_Chunk_Sub_Chunks(const ChunkImageClass * chunk) { char _buf[256]; Reset_Columns(); CListCtrl &list = GetListCtrl(); static LV_COLUMN IDColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 160, "Chunk ID", 0,0 }; static LV_COLUMN LengthColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 160, "Chunk Length", 0,0 }; list.InsertColumn(0, &IDColumn); list.InsertColumn(1, &LengthColumn); for (int i=0; iGet_Child_Count(); i++) { const ChunkImageClass * child = chunk->Get_Child(i); sprintf(_buf,"0x%08X",child->Get_ID()); int list_item = list.InsertItem(i, _buf); sprintf(_buf,"0x%08X",child->Get_Length()); list.SetItemText(list_item, 1, _buf); } } void CChunkDataView::Display_Chunk_Hex(const ChunkImageClass * chunk) { Reset_Columns(); CListCtrl &list = GetListCtrl(); static LV_COLUMN HexColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 750, "Hex Dump", 0,0 }; list.InsertColumn(0, &HexColumn); HexToStringClass * hexconverter = Create_Hex_Converter(chunk->Get_Data(),chunk->Get_Length()); assert(hexconverter != NULL); int rowcounter = 0; while (!hexconverter->Is_Done()) { list.InsertItem(rowcounter++,hexconverter->Get_Next_Line()); } Destroy_Hex_Converter(hexconverter); } void CChunkDataView::Display_Chunk_Micro_Chunks(const ChunkImageClass * chunk) { Reset_Columns(); CListCtrl &list = GetListCtrl(); static LV_COLUMN IDColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 48, "ID", 0,0 }; static LV_COLUMN LengthColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 48, "Size", 0,0 }; static LV_COLUMN DataColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 750, "Micro Chunk Data", 0,0 }; list.InsertColumn(0, &IDColumn); list.InsertColumn(1, &LengthColumn); list.InsertColumn(2, &DataColumn); int rowcounter = 0; const uint8 * workptr = chunk->Get_Data(); static char _buf[256]; while (workptr < chunk->Get_Data() + chunk->Get_Length()) { uint8 micro_id = *workptr++; uint8 micro_size = *workptr++; // Add a line for the id CString tmp_string; tmp_string.Format("%02x",micro_id); int list_item = list.InsertItem(rowcounter++, tmp_string); // Set the size (second column) tmp_string.Format("%02x",micro_size); list.SetItemText(list_item, 1, tmp_string); // Set the first line of hex data HexToStringClass * hexconverter = Create_Hex_Converter(workptr,micro_size); tmp_string = hexconverter->Get_Next_Line(); list.SetItemText(list_item, 2, tmp_string); while (!hexconverter->Is_Done()) { tmp_string = hexconverter->Get_Next_Line(); list_item = list.InsertItem(rowcounter++, ""); list.SetItemText(list_item, 2, tmp_string); } workptr += micro_size; Destroy_Hex_Converter(hexconverter); } } void CChunkDataView::Reset_Columns(void) { CListCtrl &list = GetListCtrl(); BOOL hascolumns = TRUE; while (hascolumns) { hascolumns = list.DeleteColumn(0); } } HexToStringClass * CChunkDataView::Create_Hex_Converter(const uint8 * data,const uint32 size) { HexToStringClass * hexconv = NULL; switch(WordSize) { case WORD_SIZE_LONG: hexconv = new HexToStringLongClass(data,size); break; case WORD_SIZE_SHORT: hexconv = new HexToStringShortClass(data,size); break; default: hexconv = new HexToStringByteClass(data,size); break; } return hexconv; } void CChunkDataView::Destroy_Hex_Converter(HexToStringClass * hexconv) { assert(hexconv != NULL); delete hexconv; }