forums.PPSSPP.org
Darkstalkers Chronicle: The Chaos Tower - Printable Version

+- forums.PPSSPP.org (https://forums.ppsspp.org)
+-- Forum: PPSSPP - Playstation Portable Simulator Suitable for Playing Portably (/forumdisplay.php?fid=1)
+--- Forum: Commercial Games - Compatibility and Results (/forumdisplay.php?fid=5)
+---- Forum: Playable Games (/forumdisplay.php?fid=13)
+---- Thread: Darkstalkers Chronicle: The Chaos Tower (/showthread.php?tid=1271)

Pages: 1 2 3 4


Darkstalkers Chronicle: The Chaos Tower - sfageas - 03-03-2013 03:26 PM

Region : EU
Format : ISO
Version : v0.6-903-g1b1252b
Game ID : ULES00016
OS : Win
Compatability : Ingame
Notes : Missing menu options and character selection-Invisible characters ingame


RE: Darkstalkers Chronicle The Chaos Tower - WarpRattler - 05-11-2013 11:51 AM

Region: US
Format: ISO
Version: v0.7.6-15-g9ad1c08
Game ID: ULUS10005
OS: Win7 64-bit
Compatibility: In-game
Notes: Same as above; character sprites don't show up in-game or on selection menus, and character select options such as normal/turbo and which character version you're using are invisible. The game otherwise runs normally and at full speed, albeit with no music. (My testing involved Tower mode, AKA "the only reason to play the PSP port.")


RE: Darkstalkers Chronicle The Chaos Tower - sfageas - 07-05-2013 11:43 AM

Progress!Graphics are visible but they are repeating in main menu and ingame.Game seems to hang twice,one before the intro and another one after start game,just press X to move on.All that if you disable buffered rendering.With BR it doesn't hang but the graphics are invisible

Log :
Code:
http://pastebin.com/MgfxTCQG



RE: Darkstalkers Chronicle The Chaos Tower - sfageas - 07-07-2013 05:03 PM

Black screen now with BR off(v0.8.1-401-g76c3f16)


RE: Darkstalkers Chronicle The Chaos Tower - QuarterRab - 08-31-2013 12:48 AM

I was wondering if theres any plans on getting this game running?It was my first game on the psp,I've been wanting to play it but my psp died a year ago.


RE: Darkstalkers Chronicle The Chaos Tower - NickGrouwen - 10-24-2013 08:50 AM

Yeah it doesn't work very well in v0.9.1 either once I get to character selection


RE: Darkstalkers Chronicle The Chaos Tower - GuilhermeGS2 - 11-22-2013 04:16 PM

any news?

*updating compatibility list.


RE: Darkstalkers Chronicle The Chaos Tower - synce - 01-04-2014 02:45 AM

ULJM-05005 (Japan) crashes PPSSPP v0.9.6.2 after pressing Start on the title menu. Tested with various settings, no luck getting it running.

On 0.9.1 it has the same problems others have mentioned

EDIT: Bypassed crash by downloading a clear file for the game, strange... Invisible problem persists though
EDIT 2: Game seems working fine on v096-317, just enable GPU buffer rendering


RE: Darkstalkers Chronicle The Chaos Tower - sum2012 - 01-05-2014 10:20 PM

Test on v0.9.6-342 on USA same crash
[attachment=9971]
info log: attach
debug log:
https://drive.google.com/file/d/0B3OaSdeV0L8kV3FXZjNuQ1Ztazg/edit?usp=sharing


RE: Darkstalkers Chronicle The Chaos Tower - [Unknown] - 01-06-2014 01:45 AM

It's hitting this:

Code:
    T *GetFast(SceUID handle)
    {
        const SceUID realHandle = handle - handleOffset;
        _dbg_assert_(SCEKERNEL, realHandle >= 0 && realHandle < maxCount && occupied[realHandle]); <-- BOOM
        return static_cast<T *>(pool[realHandle]);
    }

This means one of:

* The game is deleting a thread in a way that doesn't remove it from the thread queues.
* The game is writing somewhere that is corrupting PPSSPP's memory.
* A buffer overflow in PPSSPP is overwriting PPSSPP's memory.

But, your crash seems to indicate a crazy value of priority, which suggests one of the latter...

In sceKernelThread.cpp, find:

Code:
void __KernelChangeReadyState(Thread *thread, SceUID threadID, bool ready)
{
    // Passing the id as a parameter is just an optimization, if it's wrong it will cause havoc.
    _dbg_assert_msg_(SCEKERNEL, thread->GetUID() == threadID, "Incorrect threadID");
    int prio = thread->nt.currentPriority;

    if (thread->isReady())
    {
        if (!ready)
            threadReadyQueue.remove(prio, threadID);
    }
    else if (ready)
    {
        if (thread->isRunning())
            threadReadyQueue.push_front(prio, threadID);
        else
            threadReadyQueue.push_back(prio, threadID);
        thread->nt.status = THREADSTATUS_READY;
    }
}

Change to:

Code:
void __KernelChangeReadyState(Thread *thread, SceUID threadID, bool ready)
{
    // Passing the id as a parameter is just an optimization, if it's wrong it will cause havoc.
    _dbg_assert_msg_(SCEKERNEL, thread->GetUID() == threadID, "Incorrect threadID");
    int prio = thread->nt.currentPriority;
    if (prio < 0 || prio > 127) {
        NOTICE_LOG(HLE, "Wackjob crazy priority %d for thread %d", prio, threadID);
        DebugBreak();
        thread->nt.currentPriority = 127;
        return;
    }

    if (thread->isReady())
    {
        if (!ready)
            threadReadyQueue.remove(prio, threadID);
    }
    else if (ready)
    {
        if (thread->isRunning())
            threadReadyQueue.push_front(prio, threadID);
        else
            threadReadyQueue.push_back(prio, threadID);
        thread->nt.status = THREADSTATUS_READY;
    }
}

Also:

Code:
Thread *__KernelNextThread() {
    SceUID bestThread;

    // If the current thread is running, it's a valid candidate.
    Thread *cur = __GetCurrentThread();
    if (cur && cur->isRunning())
    {
        bestThread = threadReadyQueue.pop_first_better(cur->nt.currentPriority);
        if (bestThread != 0)
            __KernelChangeReadyState(cur, currentThread, true);
    }
    else
        bestThread = threadReadyQueue.pop_first();

    // Assume threadReadyQueue has not become corrupt.
    if (bestThread != 0)
        return kernelObjects.GetFast<Thread>(bestThread);
    else
        return 0;
}

Change to:

Code:
Thread *__KernelNextThread() {
    SceUID bestThread;

    // If the current thread is running, it's a valid candidate.
    Thread *cur = __GetCurrentThread();
    if (cur && cur->isRunning())
    {
        bestThread = threadReadyQueue.pop_first_better(cur->nt.currentPriority);
        if (bestThread != 0)
            __KernelChangeReadyState(cur, currentThread, true);
    }
    else
        bestThread = threadReadyQueue.pop_first();

    // Assume threadReadyQueue has not become corrupt.
    if (bestThread != 0) {
        u32 errorIgnored;
        Thread *t = kernelObjects.Get<Thread>(bestThread, errorIgnored);
        if (t == NULL && bestThread != 0) {
            NOTICE_LOG(HLE, "ACK ACK ACK ACK Invalid thread id %d on thread queue", bestThread);
            DebugBreak();
            // Try, try again?
            t = __KernelNextThread();
        }
        if (t == NULL) {
            NOTICE_LOG(HLE, "ACK ACK ACK ACK Thread queue empty");
            DebugBreak();
            // Just brute force it, hopefully...
            return kernelObjects.Get<Thread>(threadIdleID[0], errorIgnored);
        }
        return t;
    } else {
        return 0;
    }
}

(and run in the debugger.)

-[Unknown]


RE: Darkstalkers Chronicle The Chaos Tower - sum2012 - 01-06-2014 03:54 AM

@Unknown
Do you mean "run in the debugger" = run in the debug build ?

PS:I am at work,if tonight don't need overtime work,would come back home in 8 hours later


RE: Darkstalkers Chronicle The Chaos Tower - [Unknown] - 01-06-2014 06:39 AM

Yeah, with the debugger "attached" - e.g. press F5 in Visual Studio. It will break back to the code as soon as something crazy happens.

-[Unknown]


RE: Darkstalkers Chronicle The Chaos Tower - sum2012 - 01-06-2014 06:58 AM

OK.Will try when I get back home.
PS:Bad news,tonight I need overtime to work .maybe 1:00 am )hong kong time) to get back home
(01-06-2014 06:39 AM)[Unknown] Wrote:  Yeah, with the debugger "attached" - e.g. press F5 in Visual Studio. It will break back to the code as soon as something crazy happens.

-[Unknown]



RE: Darkstalkers Chronicle The Chaos Tower - sum2012 - 01-06-2014 02:20 PM

@Unknown
Attach modify code of crash trace picture
and Modify Debug log


RE: Darkstalkers Chronicle The Chaos Tower - [Unknown] - 01-06-2014 02:53 PM

Okay, so that thread is "Task Level0". It does indeed destroy that thread:

sceKernelTerminateThread(326)
sceKernelDeleteThread(326)
Freeing thread stack Task Level0

It's created with priority 32:
326=sceKernelCreateThread(name=Task Level0, entry=0885575c, prio=32, stacksize=12288)

But changed later:
sceKernelChangeThreadPriority(326, 63)
(while on that thread in fact.)

This code should be removing it from priority 32 initially:
Code:
        int old = thread->nt.currentPriority;
        threadReadyQueue.remove(old, threadID);

And this code should be removing it on delete:
Code:
    int prio = __KernelGetThreadPrio(threadID);
    if (prio != 0)
        threadReadyQueue.remove(prio, threadID);

One of these isn't working. So let's try changing them, respectively, to:

Code:
        int old = thread->nt.currentPriority;
        threadReadyQueue.remove(old, threadID);
        NOTICE_LOG(HLE, "Removed thread %d from ready queue %d", threadID, old);

Code:
    int prio = __KernelGetThreadPrio(threadID);
    if (prio != 0) {
        threadReadyQueue.remove(prio, threadID);
        NOTICE_LOG(HLE, "Removed thread %d from ready queue %d for delete", threadID, prio);
    } else {
        ERROR_LOG(HLE, "UNABLE TO REMOVE %d from ready queue %d for delete", threadID, prio);
    }

If both of those are successful, I'm not sure what's going on. We could also log here for good measure:

Code:
    inline void remove(u32 priority, const SceUID threadID)
    {
        Queue *cur = &queues[priority];
        _dbg_assert_msg_(SCEKERNEL, cur->next != NULL, "ThreadQueueList::Queue should already be linked up.");

        for (int i = cur->first; i < cur->end; ++i)
        {
            if (cur->data[i] == threadID)
            {
                int remaining = --cur->end - i;
                if (remaining > 0)
                    memmove(&cur->data[i], &cur->data[i + 1], remaining * sizeof(SceUID));
                return;
            }
        }

        // Wasn't there.
    }

Change to:

Code:
    inline void remove(u32 priority, const SceUID threadID)
    {
        Queue *cur = &queues[priority];
        _dbg_assert_msg_(SCEKERNEL, cur->next != NULL, "ThreadQueueList::Queue should already be linked up.");

        for (int i = cur->first; i < cur->end; ++i)
        {
            if (cur->data[i] == threadID)
            {
                int remaining = --cur->end - i;
                if (remaining > 0)
                    memmove(&cur->data[i], &cur->data[i + 1], remaining * sizeof(SceUID));
                return;
            }
        }

        // Wasn't there.
        ERROR_LOG(HLE, "Unable to remove thread %d from queue %d - was not there", threadID, priority);
    }

And, no rush, I can wait.

-[Unknown]