CoinOps 8 (StandAlone) Ayuda con los pointers de juegos XBOX

Estoy rebuscando en todos mis HDD y también en la web y no encuentro el pack de pointers para juegos de XBOX ya prefabricados para ahorrase la paliza de hacerlos. Se que los tuve y además eran fáciles de encontrar, pero ahora es un imposible.

Para el que tenga curiosidad un "pointer" es un fichero o dos que sirven para que el CoinOps reconozca ese juego y lo muestre en el listado. De ese modo los juegos que ya se tengan instalados también aparecen en el CoinOps aunque realmente no estén instalados en el propio emulador.

Estos pointers no lleva material con copyright
@hal9000

yo tengo los archivos txt donde viene el nombre en el que coinops ejecuta el contenido , el readme y el faq. es eso lo que buscas? . te mando un ejemplo de readme and faq.txt y de xbox.txt :

en readme and faq=

Virtual Boy
romsConsoles/VB_Gamename.zip

WonderSwan
romsConsoles/WON_Gamename.zip

X68000
romsConsoles/OldComputers/X68_Gamename.zip

XBOX
romsConsoles/XBOX_Gamename.zip (POINTER) or roms/XBOX_Gamename.zip (POINTER)
this will boot /XBOX_Gamename.xbe (This should be a created from "Xbe Shortcut Maker.exe" to tell it where to point)

MIDWAY GAMES
roms/MI_1.zip (POINTER for Mortal Kombat)
roms/MI_2.zip (POINTER for Mortal Kombat II)
roms/MI_3.zip (POINTER for NBA Jam)
roms/MI_4.zip (POINTER for NBA Jam TE)
roms/MI_5.zip (POINTER for Narc)
RomsMIDWAY/mk.zip
RomsMIDWAY/mk2.zip
RomsMIDWAY/narc.zip
RomsMIDWAY/nbajam.zip
RomsMIDWAY/nbajamte.zip
NOTE - If you want to run these games you need all 5 RomsMIDWAY roms in that folder then you can select the Pointer of which games to display



en xbox.txt =

XBOX_ShadowTheHedgehog
XBOX_ShamusDeepSeaAdventures
XBOX_SharkTale
XBOX_ShatteredUnion
XBOX_ShellShockNam67
XBOX_Shenmue2
XBOX_ShikigaminoShiro1
XBOX_ShikigaminoShiro1Evolution
XBOX_ShikigaminoShiro2
XBOX_ShinchoMahjong
XBOX_ShinMegamiTenseiNine
XBOX_ShowdownLegendsofWrestling
XBOX_Shrek1
XBOX_Shrek2
XBOX_ShrekSuperParty
XBOX_ShrekSuperSlam
XBOX_Sidearms
XBOX_SideArmsHyperDyne
XBOX_SidMeiersPirates
XBOX_SilentHill2RestlessDreams
XBOX_SilentHill4TheRoom
XBOX_SilentScopeComplete
XBOX_SimpsonsHitandRun
XBOX_SimpsonsRoadRage
XBOX_Sims1
XBOX_Sims2
XBOX_SimsBustinOut


ACTUALIZO: el pointer es un archivo .zip vacío con nombre del juego para que sea detectado por coinops 8. la ia de chats me ayudó a compilar los zips con la lista de xbox.txt. si te sirve te la paso.
Gracias compi, pero se necesita algo mas. Para los juegos de XBOX necesitas el pointer, es decir como tu bien dices ese archivo vacío con extensión ZIP que va en romsConsoles y ese no es problema. La cosa es que además necesitas otro archivo con el mismo nombre pero con extensión XBE en al raíz del CoinOPS

Ese fichero XBE es un launcher / shortcut que llama al juego en cuestión.

Por poner un ejemplo dejo este pack para el Voodoo Vince, el launcher incluido busca el juego en

E:\Games\Voodoo Vince\default.xbe
F:\Games\Voodoo Vince\default.xbe
G:\Games\Voodoo Vince\default.xbe

Pointer -> XBOX_VoodooVince.zip

Launcher -> XBOX_VoodooVince.xbe

Para que tenga vídeo hay que añadirlo en videos\XBOX\XBOX_VoodooVince.xmv


Había un pack con cientos de de ellos hechos, lo mismo que los vídeos.



El problema es que la edición de las rutas dentro del launcher las tengo que hacer a mano
@hal9000

accesos directos en xbe te los debo. tengo sólo los .zip [tomaaa]. a lo mejor los encuentras en back-ups.me
Tengo hecho los zips y los xbes los tengo creados pero no editados, me refiero que no apuntan a nada.
Es más, recuerdo que los xbes que corrían entonces tenían que llamarse las carpetas como el nombre de los pointer
Ahora con la aparición de CCI también les han cambiado el nombre en la carpeta..
@hal9000 Puedes probar este script python que he preparado con ayuda de la IA y te crea los .xbe de enlace automáticamente, crearlos los crea, pero no he podido probar que funcionen correctamente por que aún ando peleandome con mi xbox para que funcione [facepalm]

import os
import tkinter as tk
from tkinter import filedialog, messagebox, ttk, Menu

class XbeShortcutGenerator:
    def __init__(self, root):
        self.root = root
        self.root.title("Generador XBE Multi-Partición (Single File)")
        self.root.geometry("750x650")
       
        # --- Variables ---
        self.source_xbe_path = tk.StringVar()
        self.games_source_dir = tk.StringVar()
        self.output_dir = tk.StringVar()
        self.edit_path = tk.StringVar(value="Games\\")
       
        # Diccionario para guardar el estado de los checkboxes
        self.partitions_vars = {
            "C:": tk.IntVar(),
            "E:": tk.IntVar(),
            "F:": tk.IntVar(),
            "G:": tk.IntVar(),
            "R:": tk.IntVar(),
            "X:": tk.IntVar()
        }
       
        # Aquí guardaremos el "mapa" del archivo binario
        self.detected_slots = {}
        self.binary_data = None
       
        self.create_widgets()

    def create_widgets(self):
        # 1. SELECCIÓN DE XBE MUESTRA
        lf_source = ttk.LabelFrame(self.root, text="1. Plantilla XBE (Multi-Partición)", padding=10)
        lf_source.pack(fill="x", padx=10, pady=5)
       
        ttk.Entry(lf_source, textvariable=self.source_xbe_path, state="readonly").pack(side="left", fill="x", expand=True)
        ttk.Button(lf_source, text="Cargar Plantilla", command=self.load_xbe_file).pack(side="right", padx=5)

        # 2. CONFIGURACIÓN
        lf_data = ttk.LabelFrame(self.root, text="2. Configuración de Rutas", padding=10)
        lf_data.pack(fill="x", padx=10, pady=5)
       
        # Info detectada
        self.lbl_info = ttk.Label(lf_data, text="Estado: Esperando archivo...", foreground="gray")
        self.lbl_info.grid(row=0, column=0, columnspan=6, sticky="w", pady=(0, 10))

        ttk.Separator(lf_data, orient="horizontal").grid(row=1, column=0, columnspan=6, sticky="ew", pady=5)

        # Checkboxes
        ttk.Label(lf_data, text="Editar particiones:").grid(row=2, column=0, sticky="w", pady=5)
       
        frame_checks = ttk.Frame(lf_data)
        frame_checks.grid(row=3, column=0, columnspan=6, sticky="w")
       
        col = 0
        sorted_parts = sorted(self.partitions_vars.keys())
        for part in sorted_parts:
            cb = ttk.Checkbutton(frame_checks, text=part, variable=self.partitions_vars[part])
            cb.grid(row=0, column=col, padx=10)
            col += 1
           
        # Ruta intermedia
        ttk.Label(lf_data, text="Ruta intermedia (Carpeta contenedora):").grid(row=4, column=0, sticky="w", pady=(15,0))
        ttk.Entry(lf_data, textvariable=self.edit_path).grid(row=5, column=0, columnspan=6, sticky="ew")
       
        lf_data.columnconfigure(0, weight=1)

        # 3. DIRECTORIOS Y GENERACIÓN
        lf_dirs = ttk.LabelFrame(self.root, text="3. Generación", padding=10)
        lf_dirs.pack(fill="x", padx=10, pady=5)
       
        # Origen
        ttk.Label(lf_dirs, text="Origen de juegos (Click Dcho para menú):").pack(anchor="w")
        self.entry_games = ttk.Entry(lf_dirs, textvariable=self.games_source_dir)
        self.entry_games.pack(fill="x", pady=(0, 10))
       
        # Menú Contextual
        self.context_menu = Menu(self.root, tearoff=0)
        self.context_menu.add_command(label="📂 Seleccionar carpeta...", command=self.select_games_dir)
        self.entry_games.bind("<Button-3>", self.show_context_menu) # Windows/Linux
        self.entry_games.bind("<Button-2>", self.show_context_menu) # Mac
       
        # Destino
        ttk.Label(lf_dirs, text="Guardar nuevos XBE en:").pack(anchor="w")
        frame_out = ttk.Frame(lf_dirs)
        frame_out.pack(fill="x")
        ttk.Entry(frame_out, textvariable=self.output_dir).pack(side="left", fill="x", expand=True)
        ttk.Button(frame_out, text="...", width=3, command=self.select_output_dir).pack(side="right")

        # BOTÓN
        btn_create = ttk.Button(self.root, text="CREAR ATAJOS (SINGLE FILE)", command=self.generate_shortcuts)
        btn_create.pack(fill="x", padx=20, pady=20, ipady=10)

    # --- LÓGICA DE DETECCIÓN MULTI-SLOT ---
    def load_xbe_file(self):
        filename = filedialog.askopenfilename(filetypes=[("XBE", "*.xbe")])
        if not filename: return
        self.source_xbe_path.set(filename)
       
        try:
            with open(filename, "rb") as f:
                self.binary_data = bytearray(f.read())
            self.scan_for_slots()
        except Exception as e:
            messagebox.showerror("Error", f"Error al leer: {e}")

    def scan_for_slots(self):
        """Busca TODAS las ocurrencias de 'default.xbe' y mapea sus particiones."""
        self.detected_slots = {}
        data = self.binary_data
        search_term = b"default.xbe"
        search_term_upper = b"DEFAULT.XBE"
       
        cursor = 0
        found_count = 0
       
        while True:
            # Buscar ocurrencia
            idx = data.find(search_term, cursor)
            if idx == -1:
                idx = data.find(search_term_upper, cursor)
                if idx == -1: break # No hay más
           
            # Hemos encontrado un 'default.xbe' en 'idx'.
            start = idx
            while start > 0:
                if data[start] == 0x00: # Tope nulo encontrado
                    start += 1
                    break
                if (idx - start) > 260: break
                start -= 1
           
            full_path_bytes = data[start : idx + len(search_term)]
            try:
                path_str = full_path_bytes.decode('ascii', errors='ignore')
            except:
                path_str = ""

            # Detectar partición (primeros 2 chars)
            partition_key = path_str[:2].upper() # Ej: "E:", "F:"
           
            # Calcular Padding disponible
            end_padding = idx + len(search_term)
            while end_padding < len(data) and data[end_padding] == 0x00:
                end_padding += 1
           
            max_len = (end_padding - start) - 1
           
            # Guardar en diccionario si es una partición válida
            if ":" in partition_key:
                self.detected_slots[partition_key] = {
                    "start_offset": start,
                    "max_len": max_len,
                    "original_path": path_str
                }
                found_count += 1
               
                if partition_key in self.partitions_vars:
                    self.partitions_vars[partition_key].set(1)

            cursor = idx + 1

        # Actualizar UI
        found_parts = ", ".join(self.detected_slots.keys())
        self.lbl_info.config(text=f"Detectadas {found_count} rutas en particiones: {found_parts}", foreground="green")
       
        if found_count == 0:
            messagebox.showwarning("Aviso", "No se encontraron rutas terminadas en 'default.xbe' en este archivo.")

    # --- UTILIDADES ---
    def show_context_menu(self, event):
        try: self.context_menu.tk_popup(event.x_root, event.y_root)
        finally: self.context_menu.grab_release()

    def select_games_dir(self):
        d = filedialog.askdirectory();
        if d: self.games_source_dir.set(d)

    def select_output_dir(self):
        d = filedialog.askdirectory();
        if d: self.output_dir.set(d)

    # --- GENERACIÓN ---
    def generate_shortcuts(self):
        if not self.binary_data: return
        if not self.detected_slots:
            messagebox.showerror("Error", "No hay slots detectados en el archivo muestra.")
            return

        games_dir = self.games_source_dir.get()
        out_dir = self.output_dir.get()
       
        if not games_dir or not out_dir:
            messagebox.showerror("Error", "Faltan rutas de origen/destino.")
            return

        mid_path = self.edit_path.get().strip()
        if mid_path and not mid_path.endswith("\\"): mid_path += "\\"
        if mid_path.startswith("\\"): mid_path = mid_path[1:]

        try:
            games = [d for d in os.listdir(games_dir) if os.path.isdir(os.path.join(games_dir, d))]
        except Exception as e:
            messagebox.showerror("Error", str(e))
            return

        active_partitions = [k for k, v in self.partitions_vars.items() if v.get() == 1]
       
        errors = []
        count = 0

        for game in games:
            # Creamos una copia fresca de los datos base para ESTE juego
            new_file_data = bytearray(self.binary_data)
            file_has_error = False
           
            # Recorremos todas las particiones marcadas
            for part in active_partitions:
                if part not in self.detected_slots:
                    continue
               
                slot = self.detected_slots[part]
               
                drive_prefix = part + "\\"
                new_path_str = f"{drive_prefix}{mid_path}{game}\\default.xbe"
                new_path_bytes = new_path_str.encode('ascii')
               
                if len(new_path_bytes) > slot['max_len']:
                    errors.append(f"[{game}] Ruta {part} demasiado larga. Max: {slot['max_len']}")
                    file_has_error = True
                    break
               
                # Escribir en el buffer
                offset = slot['start_offset']
                available = slot['max_len'] + 1
                for k in range(available):
                    new_file_data[offset + k] = 0x00
               
                for k, b in enumerate(new_path_bytes):
                    new_file_data[offset + k] = b

            if file_has_error:
                continue

            # --- CAMBIO APLICADO AQUÍ ---
            # Nombre formato: "XBOX_" + nombreJuegoSinEspacios + ".xbe"
            game_name_clean = game.replace(" ", "")
            out_name = f"XBOX_{game_name_clean}.xbe"
            # ----------------------------

            out_path = os.path.join(out_dir, out_name)
           
            try:
                with open(out_path, "wb") as f:
                    f.write(new_file_data)
                count += 1
            except Exception as e:
                errors.append(f"Error guardando {game}: {e}")

        if errors:
            msg = f"Creados: {count}\nErrores ({len(errors)}):\n" + "\n".join(errors[:5])
            if len(errors) > 5: msg += "\n..."
            messagebox.showwarning("Resultado", msg)
        else:
            messagebox.showinfo("Éxito", f"Se han creado {count} atajos correctamente.")

if __name__ == "__main__":
    root = tk.Tk()
    style = ttk.Style()
    style.theme_use('clam')
    app = XbeShortcutGenerator(root)
    root.mainloop()
Gracias nuevamente, pero no veo claro como ese script va a insertar los nombres de las carpeta, mas cuando ha unas variables que paso a explicar.
De ejemplo voy a usar algo sencillo, como el juego Catwoman.

Este juego si lo has pasado con el dvd2xbox o de una iso mágica lo tendremos instalado mas o menos así

Unidad:\Games\Catwoman\default.xbe

Los launchres de CoinOps no les gustaba esa ruta y tenían que ser así

Unidad:\Games\XBOX_Catwoman\default.xbe

Peeeeero para colmo si son CCI vas a ver del siguiente modo

Unidad:\Games\Catwoman (USA)\default.xbe

El único listado que tengo es el CoinOps...

Soy consciente que a día de hoy no vale mucho la pena calentarse la cabeza con CoinOPS.... pero pa eso estamos, estamos pa eso [qmparto]
He tomado de ejemplo el xbe que pasaste del vodoo vince y sigue la misma estructura, si quieres pasame un listado de unas cuantas carpetas (digamos 10) de los que tienes y te creo unos de prueba, si te apetece trastear, si no, no pasa nada [beer]
He creado los launchers con la IA + Power Shell.

Por poner un ejemplo

Juego: Tom Clancy's Ghost Recon: Island Thunder

Pointer: XBOX_TomClancysGhostReconIslandThunder.zip

Launcher: XBOX_TomClancysGhostReconIslandThunder.xbe

Busca en juego en:

F:\Games\TomClancysGhostReconIslandThunder\default.xbe

F:\Games\XBOX_TomClancysGhostReconIslandThunder\default.xbe

G:\Games\TomClancysGhostReconIslandThunder\default.xbe

G:\Games\XBOX_TomClancysGhostReconIslandThunder\default.xbe

E:\Games\TomClancysGhostReconIslandThunder\default.xbe

E:\Games\XBOX_TomClancysGhostReconIslandThunder\default.xbe

Si no lo encuentra en esas rutas llama a la C:\evoxdash.xbe

No es exactamente lo que quería pero hace el apaño



Imagen
Una pregunta. ¿Para que se usa esto?
¿Es como un acceso directo?
Si, el CoinOps no es mas que un front-end y para que salgan listados los juegos de XBOX hay que hacer toda esta película.
La parte realmente dura son los vídeos de cada juego, se que existía una buena colección de ellos, pero a día de hoy están desaparecidos.

Ahora lo que estoy buscando y en esto la IA no me vale, es algún vídeo de no mas de un o dos minutos a los sumo, hecho a base de clips de un par de o tres de segundos de juegos random de xbox.
Es para usarlo de vídeo genérico para los juegos que no disponen de vídeo propio.
@hal9000

yo lo que hago es que busco los videos en youtube ,los descargo con jdownloader, los recorto con winavi 1.7.0.4734 (convirtiéndolos en .wmv 8 con resolución 640x480 para que sean compatibles con Coinops 8 ) y utilizo el "convert to xmv" .bat ó el Any2XMV 4 para que finalmente queden como .xmv
11 respuestas