You are not logged in.
- Topics: Active | Unanswered
#1 Jul 31, 2015 3:31 PM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Collision data hacking
1: xxxx xxxx] | 8 bits for the least significant part of the absolute x coordinate
2: [ww][xx xxxx | 2 bits, and then 6 bits for the most significant part of absolute x coordinate
3: [xxxx xxxx] | 8 bits for the first relative x coordinate
4: [xxxx xxxx] | 8 bits for the second relative x coordinate
5: yyyy yyyy] | 8 bits for the least significant part of the absolute y coordinate
6: [ww][yy yyyy | 2 bits, and then 6 bits for the most significant part of absolute y coordinate
7: [yyyy yyyy] | 8 bits for the first relative y coordinate
8: [yyyy yyyy] | 8 bits for the second relative y coordinate
9: zzzz zzzz] | 8 bits for the least significant part of the absolute z coordinate
10: [tt][zz zzzz | 2 bits for terrain type, and then 6 bits for the most significant part of absolute z coordinate
11: [zzzz zzzz] | 8 bits for the first relative z coordinate
12: [zzzz zzzz] | 8 bits for the second relative z coordinate
Offline
#2 Jul 31, 2015 9:00 PM
- Gekoncze
- Baby Dragon
- From: Czech Republic
- Registered: May 16, 2009
- Posts: 5,389
- Gems: 145
- Age: 30 years old
- Gender: Male
Re: Collision data hacking
Wow o.o this is incredible. I don't think I would have the patience to research it so deeply.
Offline
#3 Aug 02, 2015 7:42 AM
- CrystalFissure
- Member
- From: Adelaide
- Registered: May 16, 2015
- Posts: 77
- Gems: 0
- Gender: Male
- Website
Re: Collision data hacking
This is insane. Thanks a heap for showing this. I'll send it to Kly_Men_COmpany and see what he thinks.
Offline
#4 Aug 02, 2015 9:28 AM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Some new bits...
Directly following the collision model, there is a rather long list of byte values that also decide the type or material of triangles. Here it does not seem to be about 'not water'/'water', but different kinds of solid surfaces. First there are a lot of 191-s, which applies to the bridge triangles and makes it make that creaky wooden sound when you walk on it. Then there are lots of 193-s, which is what makes Spyro recognize the lava as lava.
I could change the bridge triangles into lava triangles and the other way around, but most of the triangles in the level don't seem to have values in this list of bytes, so I couldn't change their material. I initially thought there was a value for each triangle, but changing some of the later values made the sky disappear. How it is decided which triangles have values and which don't, I don't know.
Also, most special materials, like lava, seem to only be solid when they're within some degree of being horizontal. As walls, they pretty much don't exist.
Last edited by Sheep (Aug 02, 2015 9:39 AM)
Offline
#5 Aug 03, 2015 3:23 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
Offline
#6 Aug 03, 2015 4:52 PM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Offline
#7 Aug 03, 2015 9:33 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
var wordX,wordY,wordZ,vertX1,vertX2,vertX3,vertY1,vertY2,vertY3,vertZ1,vertZ2,vertZ3,terrT,normX,normY,normZ,normL,col1,col2,col3;
wordX=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8)|(file_bin_read_byte(buffer)<<16)|(file_bin_read_byte(buffer)<<24);
wordY=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8)|(file_bin_read_byte(buffer)<<16)|(file_bin_read_byte(buffer)<<24);
wordZ=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8)|(file_bin_read_byte(buffer)<<16)|(file_bin_read_byte(buffer)<<24);
vertX1=wordX&((1<<14)-1);
vertY1=wordY&((1<<14)-1);
vertX2=(wordX>>14)&((1<<9)-1);
vertY2=(wordY>>14)&((1<<9)-1);
vertX3=(wordX>>(14+9))&((1<<9)-1);
vertY3=(wordY>>(14+9))&((1<<9)-1);
vertX2-=(1<<9)*((vertX2&(1<<8))>0);
vertX3-=(1<<9)*((vertX3&(1<<8))>0);
vertY2-=(1<<9)*((vertY2&(1<<8))>0);
vertY3-=(1<<9)*((vertY3&(1<<8))>0);
vertZ1=wordZ&((1<<14)-1);
terrT=(wordZ>>14)&((1<<2)-1);
vertZ2=(wordZ>>(14+2))&((1<<8)-1);
vertZ3=(wordZ>>(14+2+8))&((1<<8)-1);
normX=vertZ2*vertY3-vertY2*vertZ3;
normY=vertX2*vertZ3-vertZ2*vertX3;
normZ=vertY2*vertX3-vertX2*vertY3;
normL=sqrt(normX*normX+normY*normY+normZ*normZ);
normX/=normL;
normY/=normL;
normZ/=normL;
vertX2+=vertX1;
vertX3+=vertX1;
vertY2+=vertY1;
vertY3+=vertY1;
vertZ2+=vertZ1;
vertZ3+=vertZ1;
if terrT&1 {
col1=c_blue;
col2=c_aqua;
col3=c_fuchsia;
}else{
col1=c_lime;
col2=c_yellow;
col3=c_red;
}
d3d_model_vertex_normal_color(collmodel,vertY1,vertX1,vertZ1,normY,normX,normZ,col1,1);
d3d_model_vertex_normal_color(collmodel,vertY2,vertX2,vertZ2,normY,normX,normZ,col2,1);
d3d_model_vertex_normal_color(collmodel,vertY3,vertX3,vertZ3,normY,normX,normZ,col3,1);
Offline
#8 Aug 03, 2015 10:07 PM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Last edited by Sheep (Aug 04, 2015 10:59 AM)
Offline
#9 Aug 04, 2015 9:50 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
Language: Delphi7.
Example usage in batch: (file "Spyro3_WAD.bat")
@echo off
if _%1_ == __ goto :eof
cd /D %~dp0
set name=.\Spyro3\
mkdir %name%>nul
for /L %%i in (98,2,170) do (
for /L %%j in (1,1,5) do (
echo %%i %%j
CollisionCracker.exe %1 %%i %%j %name%Coll_%%i_%%j
)
)
pause
____________________
program CollisionCracker;
{$APPTYPE CONSOLE}
uses Classes,SysUtils;
// <Color output console functions>
function GetStdHandle(std:integer):integer;stdcall;external'kernel32.dll';
function SetConsoleTextAttribute(handle,color:integer):boolean;stdcall;external'kernel32.dll';
function GetConsoleScreenBufferInfo(handle:integer;csbi:Pointer):boolean;stdcall;external'kernel32.dll';
function SetConsoleScreenBufferInfo(handle:integer;csbi:Pointer):boolean;stdcall;external'kernel32.dll';
type _csbi=record c1,c2:integer;color:word;c3,c4,c5,c6:integer;end;var def:Word;con:integer;csbi:_csbi;
procedure InitCol();begin con:=GetStdHandle(-11);GetConsoleScreenBufferInfo(con,@csbi);def:=csbi.color;end;
procedure WriteCol(str:string;col:Word);begin SetConsoleTextAttribute(con,col);Writeln(str);SetConsoleTextAttribute(con,def);end;
const cOK:Word=10;cInfo:Word=14;cErr:Word=12;
// </>
var
i,wad,sub:integer;
pos,size,pos_,size_:Cardinal;
stream:TFileStream;
tgt:string;
parts:array[1..6]of Cardinal;
procedure jump(cnt:Cardinal);
var i:integer;
off:Cardinal;
begin
for i:=1 to cnt do begin
stream.ReadBuffer(off,4);
stream.Seek(off-4,soFromCurrent);
if stream.Position>size then Abort;
end;
end;
procedure move(off:Integer);
begin
stream.Seek(off,soFromCurrent);
if stream.Position>size then Abort;
end;
procedure subfile(num:Cardinal);
var from,off,cnt:Cardinal;
begin
from:=stream.Position;
stream.Seek((num-1)*8,soFromCurrent);
stream.ReadBuffer(off,4);
stream.ReadBuffer(cnt,4);
if (off=0)or(cnt=0) then begin
WriteCol('Empty',cInfo);
Halt(0);
end;
if pos+off+cnt>size then Abort;
stream.Seek(from+off,soFromBeginning);
size:=from+off+cnt;
end;
procedure save2file(cnt:Cardinal;name:string);
var from:Cardinal;
save:TFileStream;
begin
if cnt=0 then exit;
if cnt>1024*1024*10 then Abort;
from:=stream.Position;
save:=TFileStream.Create(name,fmCreate);
save.CopyFrom(stream,cnt);
save.Free;
stream.Seek(from,soFromBeginning);
end;
function read4():cardinal;
begin
stream.ReadBuffer(Result,4);
if stream.Position>size then Abort;
end;
begin
if ParamCount<>4 then begin
Writeln('');
Writeln('CollisionCracker v1.0, Kly_Men_COmpany!');
Writeln('Usage: "input.wad" (subfile) (sublevel) "output"');
Writeln('"input.wad" = name of source WAD.WAD or an already extracted subfile.');
Writeln('(subfile) = 0 for WAD.WAD or number of subfile to take.');
Writeln('(sublevel) =0 for Spyro1, =-1 for Spyro2 and >=1 for Spyro3 sublevels.');
Writeln('"output" = main name to save resulst, also will be "output.1" .. "output.5"');
Writeln('');
exit;
end;
try
stream:=TFileStream.Create(ParamStr(1),fmOpenRead or fmShareDenyNone);
except Writeln('Open file error!');
exit;
end;
try
wad:=StrToInt64(ParamStr(2));
sub:=StrToInt64(ParamStr(3));
except Writeln('Wrong integer!');
exit;
end;
InitCol();
tgt:=ParamStr(4);
size:=stream.Size;
if wad>0 then try
subfile(wad);
except Writeln('WAD seeking error!');
exit;
end;
pos_:=stream.Position;
size_:=size;
try
if sub>1 then subfile(5+(sub-2)*2) else subfile(2);
except Writeln('SUB seeking error!');
exit;
end;
try
jump(1);
if sub>1 then move(384);
jump(3);
if sub>1 then jump(1);
if sub<0 then jump(2);
if (sub=1)or(sub=-1) then move(12);
except Writeln('SUB-SUB seeking error!');
exit;
end;
try
parts[6]:=read4()-4;
if parts[6]=0 then begin
stream.Seek(pos_,soFromBeginning);
size:=size_;
subfile(3);
move(4);
jump(2);
move(4);
parts[6]:=read4()-4;
end;
pos:=stream.Position;
save2file(parts[6],tgt);
if sub=0 then move(8) else move(12);
for i:=1 to 5 do parts[i]:=read4();
for i:=1 to 5 do begin
stream.Seek(pos+parts[i],soFromBeginning);
save2file(parts[i+1]-parts[i],tgt+'.'+IntToStr(i));
end;
except WriteCol('ERROR',cErr);
exit;
end;
WriteCol('Done!',cOK);
stream.Free;
end.
Last edited by aleksusklim (Aug 06, 2015 8:55 PM)
Offline
#10 Aug 06, 2015 10:17 PM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Last edited by Sheep (Aug 07, 2015 11:41 PM)
Offline
#11 Aug 08, 2015 3:12 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
Offline
#12 Aug 08, 2015 4:12 PM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Offline
#13 Aug 08, 2015 6:06 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
Offline
#14 Aug 08, 2015 6:47 PM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Last edited by Sheep (Aug 09, 2015 8:01 AM)
Offline
#15 Aug 09, 2015 7:35 AM
- CrystalFissure
- Member
- From: Adelaide
- Registered: May 16, 2015
- Posts: 77
- Gems: 0
- Gender: Male
- Website
Re: Collision data hacking
Last edited by CrystalFissure (Aug 09, 2015 7:38 AM)
Offline
#16 Aug 12, 2015 10:49 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
#include <bladeps.h>
u_char ot[2000];
void copy(char*from,char*to){
while(*from)*(to--)=*(from++);
}
void code(char*a0,char*a1,char*a2,char*a3){
copy(a0,(char*)0x8000000f);
copy(a1,(char*)0x801fffff);
copy(a2,(char*)0x1f80000f);
copy(a3,(char*)0x1f8003ff);
while(1);;
}
void main (void){
GsInitGraphQuick (320, 240);
GsSetWorkBase(&ot[0]);
GsSortClear(0,255,0);
GsDrawOT ((u_long *) &ot[0]);
code("!MARniaMfOtratS!","!!MARniaMfOdnE!!","!hctarcSfOtratS!","!!hctarcSfOdnE!!");
}
// "!StartOfMainRAM!","!!EndOfMainRAM!!","!StartOfScratch!","!!EndOfScratch!!"
Offline
#17 Aug 13, 2015 9:41 AM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Wow, this is really way above my experience and skill level!! I can understand it took you a few days. Also, clever way of finding the addresses!
I ran the test, using ePSXe 1.7.0 and got:
0x0094C020
9748512
The screen flickering was really painful, though, so I suggest replacing it with something else if more people need to go through it
Offline
#18 Aug 14, 2015 7:38 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
// for PS1 SDK
void copy(char*from,char*to){
while(*from)*(to--)=*(from++);
}
void code(char*a0,char*a1,char*a2,char*a3){
copy(a0,(char*)0x8000000f);
copy(a1,(char*)0x801fffff);
copy(a2,(char*)0x1f80000f);
copy(a3,(char*)0x1f8003ff);
}
#include <r3000.h>
#include <asm.h>
#include <libapi.h>
#include <sys/file.h>
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
typedef struct {
DRAWENV draw;
DISPENV disp;
} DB;
DB db[2];
DB *cdb;
int i;
main()
{
ResetGraph(0);
SetDefDrawEnv(&db[0].draw, 0, 0, 320, 240);
SetDefDispEnv(&db[0].disp, 0, 240, 320, 240);
SetDefDrawEnv(&db[1].draw, 0, 240, 320, 240);
SetDefDispEnv(&db[1].disp, 0, 0, 320, 240);
code("!MARniaMfOtratS!","!!MARniaMfOdnE!!","!hctarcSfOtratS!","!!hctarcSfOdnE!!");
// "!StartOfMainRAM!","!!EndOfMainRAM!!","!StartOfScratch!","!!EndOfScratch!!"
db[0].draw.isbg = 1;
setRGB0(&db[0].draw, 0, 255, 0);
db[1].draw.isbg = 1;
setRGB0(&db[1].draw, 0, 0, 255);
SetDispMask(1);
DrawSync(0);
VSync(0);
while(1) {
cdb = (cdb==db)?db+1:db;
PutDrawEnv(&cdb->draw);
PutDispEnv(&cdb->disp);
DrawSync(0);
for(i=0;i<60;i++)VSync(0);
}
}
Last edited by aleksusklim (Aug 14, 2015 7:42 PM)
Offline
#19 Aug 16, 2015 1:06 AM
- spyroyo
- Member
- Registered: Nov 24, 2013
- Posts: 16
- Gems: 0
Re: Collision data hacking
// for PS1 SDK
void copy(char*from,char*to){
while(*from)*(to--)=*(from++);
}
void code(char*a0,char*a1,char*a2,char*a3){
copy(a0,(char*)0x8000000f);
copy(a1,(char*)0x801fffff);
copy(a2,(char*)0x1f80000f);
copy(a3,(char*)0x1f8003ff);
}
#include <r3000.h>
#include <asm.h>
#include <libapi.h>
#include <sys/file.h>
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
typedef struct {
DRAWENV draw;
DISPENV disp;
} DB;
DB db[2];
DB *cdb;
int i;
main()
{
ResetGraph(0);
SetDefDrawEnv(&db[0].draw, 0, 0, 320, 240);
SetDefDispEnv(&db[0].disp, 0, 240, 320, 240);
SetDefDrawEnv(&db[1].draw, 0, 240, 320, 240);
SetDefDispEnv(&db[1].disp, 0, 0, 320, 240);
code("!MARniaMfOtratS!","!!MARniaMfOdnE!!","!hctarcSfOtratS!","!!hctarcSfOdnE!!");
// "!StartOfMainRAM!","!!EndOfMainRAM!!","!StartOfScratch!","!!EndOfScratch!!"
db[0].draw.isbg = 1;
setRGB0(&db[0].draw, 0, 255, 0);
db[1].draw.isbg = 1;
setRGB0(&db[1].draw, 0, 0, 255);
SetDispMask(1);
DrawSync(0);
VSync(0);
while(1) {
cdb = (cdb==db)?db+1:db;
PutDrawEnv(&cdb->draw);
PutDispEnv(&cdb->disp);
DrawSync(0);
for(i=0;i<60;i++)VSync(0);
}
}
Offline
#20 Aug 16, 2015 11:23 AM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
Offline
#21 Aug 16, 2015 3:13 PM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Finally got some time today to test out your hack, aleksusklim... Wow, this is amazing
Like... really, really amazing! So fun to stop the time, kill enemies, and then see them die all at once. Spyro suddenly got super powers!
Edit:
Playing some in Sunny Villa... apart from the fact that they don't do damage, the iron bar gates turn into what would have been deadly traps. Slowly lift, *bam* fall down, slowly lift, *bam* fall down...
Edit:
Skateboarding: I don't know how it happened, and I'm not able to replicate it, but somehow the Skateboard got more disconnected from Spyro than usual, so it looks like Spyro casually slips away from it while in the air, and then impressively lands back onto it again. Looks awesome! (although while on the ground, he sat at the back end of the Skateboard, rather than on the middle)
Last edited by Sheep (Aug 16, 2015 3:34 PM)
Offline
#22 Aug 16, 2015 9:57 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
Offline
#23 Aug 19, 2015 5:24 PM
- Sheep
- Member
- From: Norway
- Registered: Jan 24, 2008
- Posts: 983
- Gems: 0
- Birthday: 20 January
- Age: 30 years old
- Gender: Male
- Website
Re: Collision data hacking
Offline
#24 Aug 19, 2015 9:16 PM
- aleksusklim
- Member
- From: Uzbekistan
- Registered: Aug 03, 2015
- Posts: 12
- Gems: 0
- Birthday: 30 May
- Age: 31 years old
- Gender: Male
- Website
Re: Collision data hacking
buffer=NAME+'.1';
buffer=file_bin_open(buffer,0);
var zz,yy,xx,Z,Y,X,FF,Lz,Ly,Lx,Lv,mm;
mm=256;
FF=$FFFF;
Lz=0;
Z=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8);
for(zz=1;zz<=Z;zz+=1){
file_bin_seek(buffer,Lz+zz*2);
Ly=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8);
if Ly=FF then continue;
file_bin_seek(buffer,Ly);
Y=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8);
for(yy=1;yy<=Y;yy+=1){
file_bin_seek(buffer,Ly+yy*2);
Lx=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8);
if Lx=FF then continue;
file_bin_seek(buffer,Lx);
X=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8);
for(xx=1;xx<=X;xx+=1){
file_bin_seek(buffer,Lx+xx*2);
Lv=file_bin_read_byte(buffer)|(file_bin_read_byte(buffer)<<8);
if Lv=FF then continue;
d3d_model_block(myboxcollmod,(yy-1)*mm,(xx-1)*mm,(zz-1)*mm,yy*mm,xx*mm,zz*mm,1,1);
}}}
file_bin_close(buffer);
Offline
#25 Aug 20, 2015 3:40 AM
- CrystalFissure
- Member
- From: Adelaide
- Registered: May 16, 2015
- Posts: 77
- Gems: 0
- Gender: Male
- Website
Re: Collision data hacking
Offline