Added detection for the unsigned/signed short type
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / CartFilesListWin.cpp
1 //
2 // CartFilesListWin.cpp - List files in the cartridge
3 //
4 // by Jean-Paul Mari
5 //
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 //
8 // Who When What
9 // --- ---------- -----------------------------------------------------------
10 // JPM Oct./2018 Created this file, and changed position of the status bar
11 // JPM Aug./2019 Update texts descriptions
12 //
13
14 // TO DO:
15 // To allow file opening / viewing
16 // Remove/modify the 1st information, named '1', at the top
17 // To add a filter
18 //
19
20 #include "debugger/CartFilesListWin.h"
21 #include "memory.h"
22 #include "settings.h"
23 #include "debugger/DBGManager.h"
24
25
26 //
27 CartFilesListWindow::CartFilesListWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),
28 TableView(new QTableView),
29 model(new QStandardItemModel),
30 TVlayout(new QVBoxLayout),
31 Mlayout(new QVBoxLayout),
32 layout(new QVBoxLayout),
33 treeView(new QTreeView),
34 standardModel(new QStandardItemModel),
35 rootNode(new QStandardItem),
36 CartDirectory(NULL),
37 TVstatusbar(new QStatusBar),
38 fileItems(NULL),
39 nbItem(0),
40 CartUsedBytes(0),
41 CartDirType(CFL_NOTYPE)
42 {
43 setWindowTitle(tr("cartridge directory & files"));
44
45 // Set the font
46 QFont fixedFont("Lucida Console", 8, QFont::Normal);
47 fixedFont.setStyleHint(QFont::TypeWriter);
48
49 // Set the new layout with proper identation and readibility
50 #ifdef CFL_BUFFERTREAM
51 model->setColumnCount(5);
52 #else
53 model->setColumnCount(4);
54 #endif
55 model->setHeaderData(0, Qt::Horizontal, QObject::tr("File"));
56 model->setHeaderData(1, Qt::Horizontal, QObject::tr("Address"));
57 model->setHeaderData(2, Qt::Horizontal, QObject::tr("Size"));
58 model->setHeaderData(3, Qt::Horizontal, QObject::tr("Seek"));
59 #ifdef CFL_BUFFERTREAM
60 model->setHeaderData(4, Qt::Horizontal, QObject::tr("Stream"));
61 #endif
62 // Information table
63 TableView->setModel(model);
64 TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
65 TableView->setShowGrid(0);
66 TableView->setFont(fixedFont);
67 TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());
68 TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);
69 TVlayout->addWidget(TableView);
70 TVlayout->addWidget(TVstatusbar);
71
72 // Setup root
73 rootNode = standardModel->invisibleRootItem();
74 //register the model
75 treeView->setModel(standardModel);
76 treeView->expandAll();
77 Mlayout->addWidget(treeView);
78
79 // Set layouts
80 layout->addLayout(TVlayout);
81 layout->addLayout(Mlayout);
82 setLayout(layout);
83 }
84
85
86 //
87 CartFilesListWindow::~CartFilesListWindow(void)
88 {
89 }
90
91
92 //
93 void CartFilesListWindow::Reset(void)
94 {
95 standardModel->setRowCount(0);
96 model->setRowCount(0);
97 free(CartDirectory);
98 free(fileItems);
99 fileItems = NULL;
100 CartDirectory = NULL;
101 CartUsedBytes = CartNbrFiles = CartDirType = nbItem = 0;
102 }
103
104
105 //
106 void CartFilesListWindow::RefreshContents(void)
107 {
108 size_t Error;
109 char msg[1024];
110
111 if (isVisible())
112 {
113 if (!CartDirectory)
114 {
115 if (CartDirType = GetDirType())
116 {
117 if ((CartNbrFiles = GetNbrFiles()))
118 {
119 if ((CartDirectory = (CARTDIRINFO *)CreateInfos()))
120 {
121 UpdateInfos();
122 sprintf(msg, "%u files | %u bytes in cartridge", (unsigned int)CartNbrFiles, (unsigned int)CartUsedBytes);
123 Error = CFL_NOERROR;
124 }
125 else
126 {
127 sprintf(msg, "Cannot use directory");
128 Error = CFL_NODIRUSE;
129 }
130 }
131 else
132 {
133 sprintf(msg, "No files");
134 Error = CFL_NOFILESLIST;
135 }
136 }
137 else
138 {
139 sprintf(msg, "No directory found");
140 Error = CFL_NODIRECTORYLIST;
141 }
142
143 // Display status bar
144 if (Error)
145 {
146 if ((Error & CFL_WARNING))
147 {
148 TVstatusbar->setStyleSheet("background-color: lightyellow; font: bold");
149 }
150 else
151 {
152 TVstatusbar->setStyleSheet("background-color: tomato; font: bold");
153 }
154 }
155 else
156 {
157 TVstatusbar->setStyleSheet("background-color: lightgreen; font: bold");
158 }
159 TVstatusbar->showMessage(QString(msg));
160 }
161 else
162 {
163 UpdateInfos();
164 }
165 }
166 }
167
168
169 // Get files number in the cartridge directory
170 size_t CartFilesListWindow::GetNbrFiles(void)
171 {
172 switch (CartDirType)
173 {
174 case CFL_OSJAGTYPE:
175 return ((DBGManager_GetAdrFromSymbolName((char *)"OSJAG_Directory_End") - DBGManager_GetAdrFromSymbolName((char *)"OSJAG_Directory_Deb"))) / sizeof(long);
176 break;
177
178 default:
179 return 0;
180 break;
181 }
182 }
183
184
185 // Get cartridge directory type
186 size_t CartFilesListWindow::GetDirType(void)
187 {
188 if (DBGManager_GetAdrFromSymbolName((char *)"OSJAG_Directory"))
189 {
190 return CFL_OSJAGTYPE;
191 }
192 else
193 {
194 return CFL_NOTYPE;
195 }
196 }
197
198
199 // Get filename from index (starting from 0)
200 void CartFilesListWindow::GetFileInfos(CARTDIRINFO *Ptr, size_t index)
201 {
202 OSJAGDir *Adr;
203 size_t Offset;
204
205 switch (CartDirType)
206 {
207 case CFL_OSJAGTYPE:
208 Offset = DBGManager_GetAdrFromSymbolName((char *)"OSJAG_Directory_Deb") + (index * sizeof(long));
209 Adr = (OSJAGDir *)&jagMemSpace[Offset = GET32(jagMemSpace, Offset)];
210 if (strlen(Adr->Filename))
211 {
212 Ptr->PtrFilename = Adr->Filename;
213 Ptr->valid = true;
214 }
215 else
216 {
217 Ptr->PtrFilename = (char *)"(null)";
218 }
219 Ptr->PtrDataFile = GET32(jagMemSpace, Offset);
220 Ptr->SizeFile = GET32(jagMemSpace, (Offset + sizeof(long)));
221 break;
222
223 default:
224 break;
225 }
226 }
227
228
229 // Create information from the cartridge directory information
230 void *CartFilesListWindow::CreateInfos(void)
231 {
232 CARTDIRINFO *Ptr = (CARTDIRINFO *)calloc(CartNbrFiles, sizeof(CARTDIRINFO));
233 model->setRowCount(0);
234
235 for (int i = 0; i < CartNbrFiles; i++)
236 {
237 GetFileInfos(&Ptr[i], i);
238 AddFilename(Ptr[i].PtrFilename, rootNode, 0);
239 // Display row content
240 model->insertRow(i);
241 model->setItem(i, 0, new QStandardItem(QString("%1").arg(Ptr[i].PtrFilename)));
242 if (Ptr[i].SizeFile)
243 {
244 model->setItem(i, 1, new QStandardItem(QString("0x%1").arg(Ptr[i].PtrDataFile, 6, 16, QChar('0'))));
245 model->setItem(i, 2, new QStandardItem(QString("0x%1").arg(Ptr[i].SizeFile, 6, 16, QChar('0'))));
246 }
247 CartUsedBytes += Ptr[i].SizeFile;
248 }
249
250 return Ptr;
251 }
252
253
254 // Update the variables information (seek and stream buffer)
255 void CartFilesListWindow::UpdateInfos(void)
256 {
257 size_t Offset;
258
259 for (int i = 0; i < CartNbrFiles; i++)
260 {
261 // Check if file validity (exitence)
262 if (CartDirectory[i].valid)
263 {
264 // Get the current seek and tentatively check validity (must be included in the ram zone)
265 Offset = DBGManager_GetAdrFromSymbolName((char *)"OSJAG_SeekPosition") + (i * sizeof(long));
266 if ((CartDirectory[i].CurrentSeek = GET32(jagMemSpace, Offset)) < vjs.DRAM_size)
267 {
268 model->setItem(i, 3, new QStandardItem(QString("0x%1").arg(CartDirectory[i].CurrentSeek, 6, 16, QChar('0'))));
269 }
270
271 // Get stream buffer address and check validity (must be included in the ram zone)
272 Offset = DBGManager_GetAdrFromSymbolName((char *)"OSJAG_PtrBuffer") + (i * sizeof(long));
273 if (((CartDirectory[i].PtrBufferStream = GET32(jagMemSpace, Offset)) < vjs.DRAM_size) && CartDirectory[i].PtrBufferStream)
274 {
275 #ifdef CFL_BUFFERTREAM
276 model->setItem(i, 4, new QStandardItem(QString("0x%1").arg(CartDirectory[i].PtrBufferStream, 6, 16, QChar('0'))));
277 #else
278 if (!CartDirectory[i].SizeFile)
279 {
280 model->setItem(i, 1, new QStandardItem(QString("0x%1").arg(CartDirectory[i].PtrBufferStream, 6, 16, QChar('0'))));
281 }
282 #endif
283 }
284 else
285 {
286 #ifdef CFL_BUFFERTREAM
287 model->setItem(i, 4, new QStandardItem(QString("%1").arg("")));
288 #else
289 if (!CartDirectory[i].SizeFile)
290 {
291 model->setItem(i, 1, new QStandardItem(QString("%1").arg("")));
292 }
293 #endif
294 }
295 }
296 }
297 }
298
299
300 // Add source code filename in the list
301 void CartFilesListWindow::AddFilename(char *FileName, QStandardItem *root, size_t ItemPos)
302 {
303 char *Ptr = FileName;
304 Sfileitem *PtrNewFile;
305 char Buffer[255];
306 char a;
307
308 while ((a = *Ptr++) && ((a != '\\') && (a != '/')));
309
310 if (a)
311 {
312 strncpy(Buffer, FileName, (Ptr - FileName - 1));
313 Buffer[(Ptr - FileName - 1)] = 0;
314 }
315 else
316 {
317 strcpy(Buffer, FileName);
318 }
319 PtrNewFile = (Sfileitem *)AddItem(Buffer, ItemPos);
320 if (!PtrNewFile->PreviousItem)
321 {
322 PtrNewFile->PreviousItem = root;
323 root->appendRow(PtrNewFile->Item);
324 PtrNewFile->Item->setEditable(false);
325 }
326
327 if (a)
328 {
329 return (AddFilename(Ptr, PtrNewFile->Item, (ItemPos + 1)));
330 }
331 }
332
333
334 // Add item to the list
335 // Return void * on new item or already existing one
336 void *CartFilesListWindow::AddItem(char *ItemName, size_t ItemPos)
337 {
338 Sfileitem *Ptr = fileItems;
339
340 // Look for already existing item
341 for (size_t i = 0; i < nbItem; i++)
342 {
343 if ((Ptr->column == ItemPos) && !strcmp(Ptr->Item->text().toLocal8Bit().constData(), ItemName))
344 {
345 return Ptr;
346 }
347 else
348 {
349 Ptr++;
350 }
351 }
352
353 // Add item in the list
354 fileItems = (Sfileitem *)realloc(fileItems, (sizeof(Sfileitem) * ++nbItem));
355 (fileItems + (nbItem - 1))->column = ItemPos;
356 (fileItems + (nbItem - 1))->PreviousItem = NULL;
357 (fileItems + (nbItem - 1))->Item = new QStandardItem(ItemName);
358 return (fileItems + (nbItem - 1));
359 }
360
361
362 //
363 void CartFilesListWindow::keyPressEvent(QKeyEvent * e)
364 {
365 if (e->key() == Qt::Key_Escape)
366 {
367 hide();
368 }
369 }