PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Minipatch der den RPG-Maker-Bug mit dem "Division by zero error" behebt



Cherry
14.06.2013, 23:25
Ich habe vorhin einen Minipatch gemacht nachdem ich einen seltsamen "Division by zero error" eines 2k3-Projektes untersucht habe. Dieser Patch wird auch in DynRPG integriert werden.
Dieser Patch ist deshalb auch nur für RM2k3 v1.08 erhältlich.

Der Patch behebt einen Fehler im RPG Maker der dazu führen konnte dass das Spiel mit einem "Division by zero error" abgestürzt ist wenn bestimmte Pictureoperationen durchgeführt wurden, im Speziellen Randfälle wie Pictures mit kleinem Zoomlevel am Rand des Bildschirms.

Download: http://share.cherrytree.at/showfile-10156/rpg_rt_division_by_zero_bugfix.ips


Der RPG Maker verwendet eine Funktion mit der ein bestimmtes Rechteck aus einem sogenannten "Sheet" auf ein bestimmtes Zielrechteck auf einem sogenannten "Board" gezeichnet wird, dabei kann das Bild auch verzerrt werden (das wird für die Zoomfunktion verwendet). Um jetzt die Koordinaten so zu korrigieren dass Bereiche die über das Sheet oder das Board hinausragen würden gar nicht gezeichnet werden (weil das ja nicht ginge), werden die beiden Rechtecksangaben hiermit angepasst:


void __usercall FitRect(signed int *srcLeft<eax>, signed int *srcTop<edx>, signed int *x<ecx>, int dstBoardHeight, int dstBoardWidth, int srcSheetHeight, int srcSheetWidth, int *dstHeight, int *dstWidth, int *srcHeight, int *srcWidth, int *y)
{
signed int *x_; // edi@1
signed int *srcTop_; // esi@1
signed int *srcLeft_; // ebx@1

x_ = x;
srcTop_ = srcTop;
srcLeft_ = srcLeft;
FitRectCoordinate(srcLeft, x, srcWidth, srcSheetWidth, dstWidth);
FitRectCoordinate(srcTop_, y, srcHeight, srcSheetHeight, dstHeight);
FitRectCoordinate(x_, srcLeft_, dstWidth, dstBoardWidth, srcWidth);
FitRectCoordinate(y, srcTop_, dstHeight, dstBoardHeight, srcHeight);
}

void __userpurge FitRectCoordinate(signed int *srcPos<eax>, signed int *dstPos<edx>, int *srcSize<ecx>, int srcSheetSize, int *dstSize)
{
int *dstSize_; // esi@1
int srcSize_deref; // edi@2
int srcSize_deref2; // edi@5
signed int *dstPos_; // [sp+Ch] [bp-4h]@1

dstPos_ = dstPos;
dstSize_ = dstSize;
if ( *srcPos < 0 )
{
srcSize_deref = *srcSize;
*srcSize += *srcPos;
if ( *srcSize > 0 )
{
*dstSize_ = *srcSize * *dstSize_ / srcSize_deref;
*dstPos_ -= *dstSize_ * *srcPos / *srcSize;
*srcPos = 0;
}
}
if ( *srcSize + *srcPos > srcSheetSize )
{
srcSize_deref2 = *srcSize;
*srcSize = srcSheetSize - *srcPos;
*dstSize_ = *srcSize * *dstSize_ / srcSize_deref2; // Crash hier weil srcSize_deref2 == 0
if ( !*dstSize_ )
*dstSize_ = 1;
}
}

Ignoriere die teilweise mehrfach vorhandenen Variablen, der Code kommt von einem Decompiler.

An der markierten Zeile ist das Programm abgestürzt weil srcSize_deref2 da 0 war. Ich habe jetzt quasi ein if(srcSize_deref2 != 0) { ... } else { *dstSize_ = 0; } um die Zeile herumgemacht.

bugmenot
15.06.2013, 14:00
Ich habe ehrlich gesagt meine liebe Mühe, den Fehler ungepatcht zu reproduzieren. Deswegen kann ich nicht sagen, ob dies hier dem 2k (v 1.07) hilft:

0x50298 set [E8 74 05 02 00] //call sub_471411
0x70811 set [85 FF 0F 85 02 00 00 00 33 C0 C3]

0x7080C [33 D2 8B 43 18] set [E9 B3 01 00 00] **
0x708D2 [E9 ED 00 00 00] set [00 00 00 00 00]

Edit
Sorry. Vertippt. ...

**Dies sorgt dafür, dass einiges an Code übersprungen wird, welcher auftritt, wenn man einen Shop aufruft ohne Items zum Kauf gelistet zu haben.
Dort würden unter anderem folgende VocabStrings angezeigt werden (also nichts, was man vermissen sollte):


ITEMS_INVENTORY = AC 00 00 00
ITEMS_EQUIPMENT = B0 00 00 00

...und man hat noch 181 Bytes für Patches übrig.

MagicMaker
15.06.2013, 14:06
**Dies sorgt dafür, dass einiges an Code übersprungen wird, welcher auftritt, wenn man einen Shop aufruft ohne Items zum Kauf gelistet zu haben.
Dort würden unter anderem folgende VocabStrings angezeigt werden (also nichts, was man vermissen sollte):

...und man hat noch 181 Bytes für Patches übrig.
Sind die dann auch weg, wenn man einen SellOnly-Shop macht? °-°

bugmenot
15.06.2013, 14:10
Sind die dann auch weg, wenn man einen SellOnly-Shop macht? °-°

Da bleibt das noch alles beim Alten. Es wird nur im [BUY]Fenster keine Information von einer nicht vorhandenen Item-ID abgerufen (nehme ich an), sondern der VocabString ausgedruckt und noch jeweils eine 0 dahinter gesetzt.