1import weakref 2 3 4class StrWithExplicit(str): 5 6 # def __init__(self, object): 7 # super().__init__(object) 8 # self.explicit = "" 9 10 @property 11 def int(self): 12 return int(self or "0") 13 14 15class ImplicitConfig: 16 def __init__(self, config, settings): 17 self._values = {} 18 self._config = config 19 self._settings = settings 20 21 # self.__setattr__ = self.__setattr__function 22 23 def items(self): 24 return self._values.items() 25 26 def get(self, key, default=""): 27 value = self._values.get(key, default) 28 explicit = self._config[key] 29 # print(explicit) 30 if not explicit: 31 explicit = self._settings[key] 32 if value: 33 result = StrWithExplicit(value) 34 else: 35 result = StrWithExplicit(explicit) 36 result.explicit = explicit 37 return result 38 39 def __getitem__(self, item): 40 result = self.get(item) 41 # print("get", item, repr(result)) 42 return result 43 44 def __setitem__(self, key, value): 45 # print("setitem", key, value) 46 if not value: 47 value = "" 48 else: 49 value = str(value) 50 self._values[key] = value 51 52 def __getattr__(self, item): 53 result = self.get(item) 54 # print("get", item, repr(result)) 55 return result 56 # print("getattr", item) 57 # if item == "_values": 58 # return getattr(self, "_values") 59 # return self.get(item) 60 61 def __setattr__(self, key, value): 62 if key.startswith("_"): 63 self.__dict__[key] = value 64 else: 65 self[key] = value 66 67 68class NoParent: 69 def __call__(self): 70 return None 71 72 # def __nonzero__(self): 73 # return False 74 75 76class Item: 77 def __init__(self, text, active=True): 78 self.text = text 79 self.extra = "" 80 # self.parent = parent 81 self._active = active 82 self.represents = [] 83 self.parent = NoParent() 84 self.children = [] 85 86 # def set_parent(self, item): 87 # self.parent = item 88 89 @property 90 def active(self): 91 return self._active 92 93 def add(self, child): 94 child.parent = weakref.ref(self) 95 self.children.append(child) 96 97 def __str__(self): 98 return " + {0}".format(self.text) 99 100 101class ContainerItem(Item): 102 """This item is only active if it has children.""" 103 104 @property 105 def active(self): 106 # print("active???", self, len(self.children)) 107 # return True 108 return len(self.children) > 0 109 110 111class InactiveItem(Item): 112 def __init__(self, text): 113 super().__init__(text, active=False) 114 115 def __str__(self): 116 return " ( {0} )".format(self.text) 117 118 119class Model: 120 def __init__(self, show_all=False): 121 self.items = [] 122 self.show_all = show_all 123 124 def add(self, item): 125 # if item.active or self.show_all: 126 if True: 127 if item.parent: 128 for i in range(len(self.items) - 1, -1, -1): 129 if ( 130 self.items[0].parent == item.parent 131 or self.items[0] == item.parent 132 ): 133 self.items.insert(i + 1, item) 134 break 135 else: 136 self.items.append(item) 137 else: 138 self.items.append(item) 139 return item 140 141 def remove(self, item): 142 self.items.remove(item) 143 return item 144 145 def last_item(self): 146 return self.items[-1] 147 148 149def normalize(value): 150 n = "" 151 for c in value.lower(): 152 if c in "abcdefghijklmnopqrstuvwxyz0123456789+": 153 n += c 154 return n 155 156 157def create_joystick_port_item(c, num: int) -> Item: 158 # FIXME: retrieve uae_ option 159 mode = c.get("joystick_port_{0}_mode".format(num)) 160 if mode == "nothing": 161 item = InactiveItem("Joystick Port {0}".format(num)) 162 else: 163 item = Item("Joystick Port {0}".format(num)) 164 # if mode == "joystick": 165 # device_text = "[J]" 166 # elif mode == "mouse": 167 # device_text = "[M]" 168 # elif mode == "cd32_gamepad": 169 # device_text = "[C]" 170 # else: 171 # device_text = "[?]" 172 # # FIXME: auto-calculated device 173 # device = c.get("joystick_port_{0}".format(num)) 174 # if not device: 175 # device = "???" 176 # device_text += " " + device 177 # device_item = Item(device_text) 178 # item.add(device_item) 179 return item 180 181 182def create_slirp_item(c): 183 implementation = c.uae_slirp_implementation 184 if implementation == "auto": 185 name = "Auto" 186 elif implementation == "none": 187 name = "None" 188 elif implementation == "builtin": 189 name = "Built-in" 190 elif implementation == "qemu": 191 name = "QEMU" 192 else: 193 name = implementation 194 slirp_item = Item("Slirp ({})".format(name)) 195 196 if c.uae_slirp_ports: 197 slirp_ports_item = Item("Ports: " + c.uae_slirp_ports) 198 slirp_item.add(slirp_ports_item) 199 if c.uae_slirp_redir: 200 slirp_redirect_item = Item("Redirect: " + c.uae_slirp_redir) 201 slirp_item.add(slirp_redirect_item) 202 203 return slirp_item 204 205 206def create_model(c, show_all=False): 207 model = Model(show_all=show_all) 208 209 # if c.ntsc_mode: 210 # model_item = Item(c.int_model_name + " NTSC") 211 # else: 212 # model_item = Item(c.int_model_name + " PAL") 213 # model_item.represents = ["amiga_model", "ntsc_mode"] 214 # model.add(model_item) 215 216 text = c.int_chipset_name 217 if c.uae_chipset_compatible != "-": 218 text += " ({0})".format(c.uae_chipset_compatible) 219 if c.ntsc_mode: 220 text += " NTSC" 221 else: 222 text += " PAL" 223 chipset_item = Item(text) 224 chipset_item.represents = [ 225 "uae_chipset", 226 "uae_chipset_compatible", 227 "ntsc_mode", 228 ] 229 model.add(chipset_item) 230 231 if c.uae_chipset == "aga": 232 text = "Alice (AGA)" 233 if c.ntsc_mode: 234 text += " NTSC" 235 else: 236 text += " PAL" 237 # alice_item = Item(text) 238 # chipset_item.add(alice_item) 239 # lisa_item = Item("Lisa (AGA)") 240 # chipset_item.add(lisa_item) 241 # paula_item = Item("Paula (AGA)") 242 # chipset_item.add(paula_item) 243 else: 244 # http://en.wikipedia.org/wiki/MOS_Technology_Agnus 245 if c.uae_chipset in ["ecs_agnus", "ecs"]: 246 text = "Agnus (ECS)" 247 else: 248 text = "Agnus" 249 if c.ntsc_mode: 250 text += " NTSC" 251 else: 252 text += " PAL" 253 # agnus_item = Item(text) 254 # chipset_item.add(agnus_item) 255 # if c.uae_chipset in ["ecs_denise", "ecs"]: 256 # denise_item = Item("Denise (ECS)") 257 # else: 258 # denise_item = Item("Denise") 259 # chipset_item.add(denise_item) 260 # if c.uae_chipset in ["ecs"]: 261 # paula_item = Item("Paula") 262 # else: 263 # paula_item = Item("Paula") 264 # chipset_item.add(paula_item) 265 266 # if c.kickstart_file: 267 # kickstart_item = Item("Custom Kickstart [FIXME]") 268 # else: 269 # kickstart_item = Item("Default Kickstart [FIXME]") 270 kickstart_item = Item( 271 "Kickstart {} Rev {}".format( 272 c.int_kickstart_version, c.int_kickstart_revision 273 ) 274 ) 275 model.add(kickstart_item) 276 277 if c.int_kickstart_ext_sha1 == "5bef3d628ce59cc02a66e6e4ae0da48f60e78f7f": 278 kickstart_ext_item = Item("CD32 Extended ROM") 279 elif ( 280 c.int_kickstart_ext_sha1 == "7ba40ffa17e500ed9fed041f3424bd81d9c907be" 281 ): 282 kickstart_ext_item = Item("CDTV Extended ROM") 283 else: 284 kickstart_ext_item = InactiveItem("Extended ROM") 285 model.add(kickstart_ext_item) 286 287 # if c.uae_cd32cd == "true": 288 # akiko_item = Item("Akiko Chip") 289 # # chipset_item.add(akiko_item) 290 # model.add(akiko_item) 291 292 jit_text = " [JIT]" if c.jit_compiler == "1" else "" 293 cpu_item = Item("MC" + c.int_cpu_name + jit_text) 294 cpu_item.represents = ["cpu", "uae_cpu_model"] # FIXME: uae_cpu_type 295 296 if c.int_accelerator_name: 297 item = Item("{0}".format(c.int_accelerator_name)) 298 accelerator_item = model.add(item) 299 else: 300 accelerator_item = InactiveItem("No Accelerator") 301 model.add(accelerator_item) 302 accelerator_item.represents = ["accelerator", "uae_cpuboard_type"] 303 304 if accelerator_item.active: 305 accelerator_item.add(cpu_item) 306 else: 307 model.add(cpu_item) 308 309 if accelerator_item.active: 310 if c.int_ppc_model: 311 item = Item("PowerPC {0}".format(c.int_ppc_model)) 312 accelerator_item.add(item) 313 314 # model.remove(cpu_item) 315 # cpu_item.set_parent(accelerator_item) 316 # model.add(cpu_item) 317 318 if c.int_cpuboardmem1_size: 319 size = "{0} MB".format( 320 int(c.int_cpuboardmem1_size) // (1024 * 1024) 321 ) 322 item = Item("{0} RAM".format(size)) 323 item.represents = ["uae_cpuboard1mem_size"] 324 accelerator_item.add(item) 325 326 item = Item("ROM/Flash [FIXME]") 327 item.represents = ["accelerator_rom"] 328 accelerator_item.add(item) 329 330 if c.uae_cpuboard_type == "CyberStormPPC": 331 # FIXME: other too? 332 accelerator_scsi_item = Item("CyberStorm SCSI") 333 accelerator_item.add(accelerator_scsi_item) 334 335 if int(c.uae_mmu_model): 336 mmu_item = Item("{0} MMU".format(c.uae_mmu_model)) 337 else: 338 mmu_item = InactiveItem("No MMU") 339 cpu_item.represents = ["mmu_model"] 340 cpu_item.add(mmu_item) 341 342 if int(c.uae_fpu_model): 343 fpu_item = Item("{0} FPU".format(c.uae_fpu_model)) 344 else: 345 fpu_item = InactiveItem("No FPU") 346 # fpu_item.set_parent(cpu_item) 347 fpu_item.represents = ["fpu_model"] 348 if c.uae_fpu_model == c.uae_cpu_model: 349 cpu_item.add(fpu_item) 350 else: 351 model.add(fpu_item) 352 353 if int(c.int_chipmem_size) % (1024 * 1024) == 0: 354 size = "{0} MB".format(int(c.int_chipmem_size) // (1024 * 1024)) 355 else: 356 size = "{0} KB".format(int(c.int_chipmem_size) // 1024) 357 chipmem_item = Item("{0} Chip RAM".format(size)) 358 chipmem_item.represents = ["chip_memory", "uae_chipmem_size"] 359 model.add(chipmem_item) 360 361 if int(c.int_mbresmem_low_size): 362 size = "{0} MB".format(int(c.int_mbresmem_low_size) // (1024 * 1024)) 363 item = Item("{0} Fast RAM".format(size)) 364 else: 365 item = InactiveItem("No Fast RAM") 366 item.extra = "Motherboard" 367 item.represents = ["uae_a3000mem_size"] 368 model.add(item) 369 370 trapdoor_item = ContainerItem("Trapdoor Slot") 371 zorro_ii_item = ContainerItem("Zorro II Bus") 372 zorro_iii_item = ContainerItem("Zorro III Bus") 373 374 flatten = True 375 376 if int(c.int_bogomem_size): 377 if int(c.int_bogomem_size) % (1024 * 1024) == 0: 378 size = "{0} MB".format(int(c.int_bogomem_size) // (1024 * 1024)) 379 else: 380 size = "{0} KB".format(int(c.int_bogomem_size) // 1024) 381 bogomem_item = Item("{0} Slow RAM".format(size)) 382 else: 383 bogomem_item = InactiveItem("No Slow RAM") 384 bogomem_item.represents = ["slow_memory", "uae_bogomem_size"] 385 if flatten: 386 bogomem_item.extra = "Trapdoor" 387 model.add(bogomem_item) 388 else: 389 trapdoor_item.add(bogomem_item) 390 391 if int(c.int_fastmem_size): 392 if int(c.int_fastmem_size) % (1024 * 1024) == 0: 393 size = "{0} MB".format(int(c.int_fastmem_size) // (1024 * 1024)) 394 else: 395 size = "{0} KB".format(int(c.int_fastmem_size) // 1024) 396 # fastmem_item = Item("{0} Zorro II Fast RAM".format(size)) 397 fastmem_item = Item("{0} Fast RAM".format(size)) 398 else: 399 fastmem_item = InactiveItem("No Zorro II Fast RAM") 400 fastmem_item.represents = ["fast_memory", "uae_fastmem_size"] 401 if flatten: 402 fastmem_item.extra = "Zorro II" 403 model.add(fastmem_item) 404 else: 405 zorro_ii_item.add(fastmem_item) 406 407 if int(c.int_z3fastmem_size): 408 size = "{0} MB".format(int(c.int_z3fastmem_size) // (1024 * 1024)) 409 # z3fastmem_item = Item("{0} Zorro III Fast RAM".format(size)) 410 z3fastmem_item = Item("{0} Fast RAM".format(size)) 411 else: 412 z3fastmem_item = InactiveItem("No Zorro III Fast RAM") 413 z3fastmem_item.represents = ["zorro_iii_memory", "uae_z3mem_size"] 414 if flatten: 415 z3fastmem_item.extra = "Zorro III" 416 model.add(z3fastmem_item) 417 else: 418 zorro_iii_item.add(z3fastmem_item) 419 420 if c.uae_rtc != "none": 421 rtc_item = Item("{0} RTC".format(c.uae_rtc)) 422 else: 423 rtc_item = InactiveItem("No Real Time Clock") 424 rtc_item.represents = ["uae_rtc"] 425 if bogomem_item.active and c.uae_rtc == "MSM6242B": 426 if flatten: 427 # bogomem_item.add(rtc_item) 428 model.add(rtc_item) 429 else: 430 trapdoor_item.add(rtc_item) 431 else: 432 model.add(rtc_item) 433 434 if c.uae_cd32fmv == "true": 435 436 fmv_item = Item("CD32 FMV Module") 437 model.add(fmv_item) 438 439 fmv_rom_item = Item("CD32 FMV ROM") 440 fmv_item.add(fmv_rom_item) 441 442 model.add(trapdoor_item) 443 model.add(zorro_ii_item) 444 model.add(zorro_iii_item) 445 446 # resident_item = ContainerItem("Resident Libraries") 447 # model.add(resident_item) 448 resident_item = model 449 450 if c.int_uae_boot_rom == "true": 451 uae_boot_rom_item = Item("UAE Boot ROM") 452 resident_item.add(uae_boot_rom_item) 453 454 uae_resource_item = Item("UAE uae.resource") 455 uae_boot_rom_item.add(uae_resource_item) 456 457 if c.uae_bsdsocket_emu == "true": 458 bsdsocket_item = Item("UAE bsdsocket.library") 459 else: 460 bsdsocket_item = InactiveItem("No bsdsocket.library") 461 bsdsocket_item.represents = ["bsdsocket_library", "uae_bsdsocket_emu"] 462 resident_item.add(bsdsocket_item) 463 464 if c.uae_native_code == "true": 465 uaenative_library_item = Item("UAE uaenative.library") 466 else: 467 uaenative_library_item = InactiveItem("No uaenative.library") 468 uaenative_library_item.represents = [ 469 "uaenative.library", 470 "uae_native_code", 471 ] 472 resident_item.add(uaenative_library_item) 473 474 if c.uae_sana2 == "true": 475 uaenet_device_item = Item("UAE uaenet.device") 476 else: 477 uaenet_device_item = InactiveItem("No uaenet.device") 478 uaenet_device_item.represents = ["uae_sana2"] 479 resident_item.add(uaenet_device_item) 480 481 # if c.uae_a2065: 482 # a2065_item = Item("A2065 [Network Card]") 483 # a2065_item.represents = ["uae_a2065"] 484 # zorro_ii_item.add(a2065_item) 485 # 486 # if c.uae_a2065 == "slirp": 487 # slirp_item = create_slirp_item(c) 488 # a2065_item.add(slirp_item) 489 490 if c.uae_gfxcard_type: 491 graphics_card_item = Item( 492 "{} {} MB".format(c.int_graphics_card_name, c.uae_gfxcard_size) 493 ) 494 if flatten: 495 if c.int_graphics_card_bus == "zorro-ii": 496 graphics_card_item.extra = "Zorro II" 497 elif c.int_graphics_card_bus == "zorro-iii": 498 graphics_card_item.extra = "Zorro III" 499 model.add(graphics_card_item) 500 elif c.int_graphics_card_bus == "zorro-ii": 501 zorro_ii_item.add(graphics_card_item) 502 elif c.int_graphics_card_bus == "zorro-iii": 503 zorro_iii_item.add(graphics_card_item) 504 else: 505 model.add(graphics_card_item) 506 507 if c.uae_toccata == "true": 508 sound_card_item = Item("Toccata") 509 sound_card_item.represents = ["sound_card", "uae_toccata"] 510 if flatten: 511 sound_card_item.extra = "Zorro II" 512 model.add(sound_card_item) 513 else: 514 zorro_ii_item.add(sound_card_item) 515 516 if c.uae_a2065: 517 network_card_item = Item("A2065") 518 network_card_item.represents = ["network_card", "uae_a2065"] 519 if flatten: 520 network_card_item.extra = "Zorro II" 521 model.add(network_card_item) 522 else: 523 zorro_ii_item.add(network_card_item) 524 525 joystick_port_0_item = create_joystick_port_item(c, 0) 526 joystick_port_1_item = create_joystick_port_item(c, 1) 527 joystick_port_2_item = create_joystick_port_item(c, 2) 528 joystick_port_3_item = create_joystick_port_item(c, 3) 529 530 model.add(joystick_port_0_item) 531 model.add(joystick_port_1_item) 532 # parallel_port_item = Item("Parallel Port") 533 534 if joystick_port_2_item.active or joystick_port_3_item.active: 535 parallel_port_item = Item("Parallel Port Joystick Adapter") 536 model.add(parallel_port_item) 537 parallel_port_item.add(joystick_port_2_item) 538 parallel_port_item.add(joystick_port_3_item) 539 else: 540 parallel_port_item = InactiveItem("No Parallel Port Device") 541 model.add(parallel_port_item) 542 543 for i in range(4): 544 drive_type = getattr(c, "uae_floppy{0}type".format(i)) 545 if drive_type == "0": 546 description = '3.5" DD' 547 elif drive_type == "1": 548 description = '3.5" HD' 549 elif drive_type == "2": 550 description = '5.25" SD' 551 elif drive_type == "3": 552 description = '3.5" DD (ESCOM)' 553 else: 554 description = None 555 if description: 556 drive_item = Item( 557 "{0} Floppy Drive [DF{1}]".format(description, i) 558 ) 559 else: 560 drive_item = InactiveItem("No Floppy Drive [DF{0}]".format(i)) 561 drive_item.represents = [ 562 "floppy_drive_{0}".format(i), 563 "uae_df{0}type".format(i), 564 ] 565 model.add(drive_item) 566 # path = getattr(c, "uae_floppy{0}".format(i)) 567 # if path: 568 # name = os.path.basename(path) 569 # disk_item = Item(name) 570 # drive_item.add(disk_item) 571 572 return model 573