1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#include "OSystem.hxx"
19#include "Settings.hxx"
20#include "FrameBuffer.hxx"
21#include "FBSurface.hxx"
22#include "Font.hxx"
23#include "Dialog.hxx"
24#include "DialogContainer.hxx"
25#include "RomListWidget.hxx"
26#include "RomListSettings.hxx"
27
28// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
29RomListSettings::RomListSettings(GuiObject* boss, const GUI::Font& font)
30 : Dialog(boss->instance(), boss->parent()),
31 CommandSender(boss),
32 _xorig(0),
33 _yorig(0),
34 _item(0)
35{
36 const int buttonWidth = font.getStringWidth("RunTo PC @ current line") + 20,
37 buttonHeight = font.getLineHeight() + 4;
38 int xpos = 8, ypos = 8;
39 WidgetArray wid;
40
41 // Set PC to current line
42 ButtonWidget* setPC =
43 new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
44 "Set PC @ current line", RomListWidget::kSetPCCmd);
45 wid.push_back(setPC);
46
47 // RunTo PC on current line
48 ypos += buttonHeight + 4;
49 ButtonWidget* runtoPC =
50 new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
51 "RunTo PC @ current line", RomListWidget::kRuntoPCCmd);
52 wid.push_back(runtoPC);
53
54 // Re-disassemble
55 ypos += buttonHeight + 4;
56 ButtonWidget* disasm =
57 new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
58 "Re-disassemble", RomListWidget::kDisassembleCmd);
59 wid.push_back(disasm);
60
61 // Settings for Distella
62 xpos += 4; ypos += buttonHeight + 8;
63 myShowTentative = new CheckboxWidget(this, font, xpos, ypos,
64 "Show tentative code", RomListWidget::kTentativeCodeCmd);
65 wid.push_back(myShowTentative);
66 ypos += buttonHeight + 4;
67 myShowAddresses = new CheckboxWidget(this, font, xpos, ypos,
68 "Show PC addresses", RomListWidget::kPCAddressesCmd);
69 wid.push_back(myShowAddresses);
70 ypos += buttonHeight + 4;
71 myShowGFXBinary = new CheckboxWidget(this, font, xpos, ypos,
72 "Show GFX as binary", RomListWidget::kGfxAsBinaryCmd);
73 wid.push_back(myShowGFXBinary);
74 ypos += buttonHeight + 4;
75 myUseRelocation = new CheckboxWidget(this, font, xpos, ypos,
76 "Use address relocation", RomListWidget::kAddrRelocationCmd);
77 wid.push_back(myUseRelocation);
78
79 // Set real dimensions
80 _w = buttonWidth + 20;
81 _h = ypos + buttonHeight + 8;
82
83 addToFocusList(wid);
84
85 // We don't have a close/cancel button, but we still want the cancel
86 // event to be processed
87 processCancelWithoutWidget(true);
88}
89
90// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
91void RomListSettings::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int data)
92{
93 uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
94 _xorig = bossRect.x() + x * scale;
95 _yorig = bossRect.y() + y * scale;
96
97 // Only show if we're inside the visible area
98 if(!bossRect.contains(_xorig, _yorig))
99 return;
100
101 _item = data;
102 open();
103}
104
105// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
106void RomListSettings::center()
107{
108 // First set position according to original coordinates
109 surface().setDstPos(_xorig, _yorig);
110
111 // Now make sure that the entire menu can fit inside the screen bounds
112 // If not, we reset its position
113 if(!instance().frameBuffer().screenRect().contains(
114 _xorig, _yorig, surface().dstRect()))
115 surface().setDstPos(_xorig, _yorig);
116}
117
118// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
119void RomListSettings::loadConfig()
120{
121 myShowTentative->setState(instance().settings().getBool("dis.resolve"));
122 myShowAddresses->setState(instance().settings().getBool("dis.showaddr"));
123 myShowGFXBinary->setState(instance().settings().getString("dis.gfxformat") == "2");
124 myUseRelocation->setState(instance().settings().getBool("dis.relocate"));
125}
126
127// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
128void RomListSettings::handleMouseDown(int x, int y, MouseButton b, int clickCount)
129{
130 // Close dialog if mouse click is outside it (simulates a context menu)
131 // Otherwise let the base dialog class process it
132 if(x >= 0 && x < _w && y >= 0 && y < _h)
133 Dialog::handleMouseDown(x, y, b, clickCount);
134 else
135 close();
136}
137
138// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
139void RomListSettings::handleCommand(CommandSender* sender, int cmd, int data, int id)
140{
141 // We remove the dialog when the user has selected an item
142 // Make sure the dialog is removed before sending any commands,
143 // since one consequence of sending a command may be to add another
144 // dialog/menu
145 close();
146
147 switch(cmd)
148 {
149 case RomListWidget::kSetPCCmd:
150 case RomListWidget::kRuntoPCCmd:
151 {
152 sendCommand(cmd, _item, -1);
153 break;
154 }
155 case RomListWidget::kDisassembleCmd:
156 {
157 sendCommand(cmd, -1, -1);
158 break;
159 }
160 case RomListWidget::kTentativeCodeCmd:
161 {
162 sendCommand(cmd, myShowTentative->getState(), -1);
163 break;
164 }
165 case RomListWidget::kPCAddressesCmd:
166 {
167 sendCommand(cmd, myShowAddresses->getState(), -1);
168 break;
169 }
170 case RomListWidget::kGfxAsBinaryCmd:
171 {
172 sendCommand(cmd, myShowGFXBinary->getState(), -1);
173 break;
174 }
175 case RomListWidget::kAddrRelocationCmd:
176 {
177 sendCommand(cmd, myUseRelocation->getState(), -1);
178 break;
179 }
180 }
181}
182