«Вот бы распаковать эти игровые архивы и посмотреть что там внутри!», — наверное думал про себя, хотя бы раз, каждый геймер, который хотел понять, как устроена его любимая игра.
К счастью, сегодня большинство разработчиков не только не препятствуют изучению своих игр, но даже наоборот, делают всё, для того, чтобы игроки изменяли и дополняли игры сами. Но даже если официальной документации нет, то для 99% игр можно найти уже готовые программы для распаковки.
Я решил написать эту статью для того чтобы показать, что даже если вы столкнулись с очень редкой, старой или никому не нужной игрой, архивы которой не берет ни один «распаковщик», то даже с минимальными знаниями какого-нибудь языка программирования, вполне возможно вам удастся справится самому и стать первым, кто сможет распотрошить эту игру до косточек.
Так как само по себе, описание устройства игровых архивов вряд ли принесет какую-нибудь пользу, я опишу весь путь, который я проделал в ходе изучения игровых архивов, ход своих мыслей, а также ошибки, которые привели меня в тупики.
Структура папок тома SLPS_01060
E:.
¦ CG.FFD
¦ DUMMY3M.DA
¦ FFANM.APK
¦ FF_OPN.LPK
¦ FF_SYS.LPK
¦ NPK_ACC.NPK
¦ NPK_BOU.NPK
¦ NPK_DF.NPK
¦ NPK_DF2.NPK
¦ NPK_ETC.NPK
¦ NPK_MAIN.NPK
¦ NPK_MAKE.NPK
¦ NPK_MON.NPK
¦ NPK_WEP.NPK
¦ NPK_WM.NPK
¦ SLPS_010.60
¦ SYSTEM.CNF
¦
+---BG
¦ DATF001.LPK
¦ .....
¦ DATF009.LPK
¦
+---HERO
¦ HERO.FFD
¦
+---ITEM
¦ L---MATER
¦ MATER.FFD
¦
+---MAKINGCG
¦ MAKINGCG.NPK
¦
+---R3D
¦ RIDE_0.NPK
¦
+---S1G
¦ INST_M.S1G
¦ INST_P.S1G
¦ TITLE.S1G
¦
+---SM
¦ SM000.FFD
¦ SM001.FFD
¦
+---STR
¦ PP07FFA.STR
¦ PP07FFB.STR
¦ PP07FFC.STR
¦ PP07FFD.STR
¦ PP07FFE.STR
¦
+---TEXT
¦ MLIST.LPK
¦
L---TOWN
FF_TTOWN.NPK
Тут я хотел бы сделать небольшое отступление. Не смотря на то, что в самом начале я сказал, что особых знаний для копания в ресурсах не нужно. Есть одно «небольшое» исключение. Нужно иметь хотя бы базовое представление о том, как именно в памяти или на диске могут хранится какие-нибудь данные, в самом простом виде — числа. Другими словами нужно знать что такое Big Endian и Little Endian.Причем на первый взгляд, почти все файлы, независимо от расширения и LPK и ТЗЛ и FFD, имели очень схожую структуру в самом начале.
Я попробую объяснить суть максимально кратко:
Очень часто числа или символы хранятся в памяти в обратном порядке. Например число «16830», которое в HEX выглядит как «41 BE», а будучи переменной типа int как «00 00 41 BE» в самой памяти может хранится как «BE 41 00 00», не буду объяснять почему так(вы можете погуглить сами), скажу просто что «компьютеру так удобнее». И соответственно, таким же образом, в обратном порядке, данные могут хранится в файле на диске.
lzss, что в общем-то походило на то, что было у меня.
Parts of the original data uncompressed.
static CircularFifoQueue<Byte> circularBuffer = new CircularFifoQueue<>(4096);
private static void processNPK() {
FileInputStream fis = new FileInputStream(new File("NPK_WEP.NPK"));
ByteBuffer b1kb = ByteBuffer.allocate(1024);
while (fis.read(b1kb.array()) != -1) {
int blocksInMegaBlockCount = EndianUtils.swapInteger(b1kb.getInt());
int compressedDataLenght = EndianUtils.swapShort(b1kb.getShort());
int decompressedDataLenght = EndianUtils.swapShort(b1kb.getShort());
while (b1kb.position()<compressedDataLenght) {
readLZSBlock(b1kb);
}
if (blocksInMegaBlockCount == 1) {dumpFile(result);}
}
}
private static void readLZSBlock(ByteBuffer bb){
byte controlByte = bb.get();
for (int i = 0; i < 8; i++) {
if (isLiteral(controlByte,i)) {
byte b = bb.get();
circularBuffer.add(b);
result.write(b);
}
else result.write(getFromCBuffer(bb));
}
}
private static byte[] getFromCBuffer(ByteBuffer bb) {
byte first = bb.get();
byte second = bb.get();
Integer lowNibble = Integer.valueOf(second & 0x0f);
Integer highNibble = Integer.valueOf(((second & 0xf0) >> 4));
int offset = EndianUtils.readSwappedShort(new byte[] {first, highNibble.byteValue()}, 0);
byte[] bytesFromBuffer = new byte[lowNibble+3];
for (int i = 0; i < (lowNibble+3); i++) {
byte b = circularBuffer.get(offset);
circularBuffer.add(b);
bytesFromBuffer[i]=b;
}
return bytesFromBuffer;
}
private static boolean isLiteral(byte controlByte, int position) {
if (((controlByte >> position) & 1) == 1) return true;
else return false;
}
// чтение нормального офсета из файла
int offset = EndianUtils.readSwappedShort(new byte[] {first, highNibble.byteValue()}, 0);
// формула из статьи(где OUTPOS - количество записанных в буфер данных)
int realoffset = OUTPOS - ((OUTPOS + 0xfee - offset) & 0xfff);
//натягивания формулы из статьи на мой "кольцевой буфер"
int realoffset2 = 4096 - OUTPOS + realoffset;
public class ByteRingBuffer {
private byte[] rBuf; // ring buffer data
public int rBufSize = 4096; // ring buffer size
public int writeReadOffsetCorrection = 18;
public int lenghtCorrectionLZS = 3;
private int rBufWrPos = rBufSize - writeReadOffsetCorrection; // position of first (oldest) data byte within the ring buffer
public ByteRingBuffer() {
rBuf = new byte[rBufSize];
}
public byte write(byte bt) {
rBuf[rBufWrPos++] = bt;
if (rBufWrPos == rBufSize)
rBufWrPos = 0;
return bt;
}
public byte read(int offset) {
return rBuf[offset & 0xfff];
}
}
<libetc.h>
#include <libgte.h>
#include <libgpu.h>
#include <libsnd.h>
#include <libgs.h>
#include <KERNEL.H>
#include <libsn.h>
#include <libcd.h>
*************************************************************************/
#include "ff.h"
//#include "ff7list.h"
#include "winsys.h"
#include "cursol.h"
#include "datafanm.inc"
#include "dataflpk.inc"
#include "lpk_sys.inc"
#include "ffaku.h"
#include "clickm.h"
#include "npk_item.inc"
/*****************************************************************************/
/* ??? */
Z_CLUT, (long *)LPKBuf, (long *)ComnBuf
#define DEFSET LZ_TIM | LZ_CLUT, (long *)MODELBuf, (long *)ComnBuf
#define DEFSYS LZ_TIM | LZ_CLUT, (long *)SYSBuf, (long *)ComnBuf
#define SUBBERMAX 3
#define SUBBERMAX 3
#define ZENGAMEN_X 168 /* ???X?? */
#define ZIGAMEN_X 282 /* ???X?? */
#define ZIGAMEN_Y 16, 17};
_BOXFTAG EXsubbox[SUBBERMAX]; /* ????????? */
static int wait; /* ???? */
static int oldx; /* ???X??????? */
static int oldy; /* ???Y??????? */
static int oldpad; /* ?????????
/* ?? */
static int mode; /* ??????????? */
static int Shop_Sel; /* ???????????? */
int EXdatflag; /* ??????????? */
int EXdatnum; /* ?? */
static char /*???BG??????? */
extern _BOXFTAG EXbox01; /* ???? */
/*****************************************************************************/
/* ???????? */
/*****************************************************************************/
void Item_? /* */
void ItemSelLoadEX(void); /*???????????????????(?????)??*/
void ShopList(void); /* ??????????? */
void ShopSel(void); /* ????????? */
/* */
/* 1997/05/07 G.T.V H.Mizukami */
/**************************** */
LLbox.r = 1;
LLbox.g = 1;
LLbox.b = 1;
LLbox.x = 16-256;
LLbox.y = 20-120;
LLbox.w = 332;
LLbox.h = 16;
GsSort i = i - LLtbl[Q1];
if(i < 0)
{
ListPage[Q1] = n + 0x30;
i = i + LLtbl[Q1];
*/
/* 1997/03/26 G.T.V H.Mizukami */
/********************/
strcat(mlistbuf, akuselist[LLtop + Q1]);
break;
case 4: /* ??? */
strcat(mli
/**/
/* 1997/04/22 G.T.V H.Mizukami */
/*****************************************************************************/
void Item_SelMenuInit(void)
{
WinFill LLwin;
A/* ???????? */
case 4: /* ?????? */
ListInit(item_menu);
WinSetPos(wid[2], 128, 44, 16*20, 14*10);
WinSetRGB(wid[2], 0, 0, 255, RGB_BUL);
break;
/* H.Mizukami */
/*****************************************************************************/
void Item_SelMenu(void)
{
int LLnum;
MjsLoop(&EXtprm01);
if((LLnum = MjsMenuStat(&EXtprm01)) == -1)
return;
/*se */
/* 1997/04/25 G.T.V H.Mizukami */
/*****************************************************************************/
void Item_Mat_SelInit(void)
{
WinFill LLwin;
command = 2;
EXsubbox[0].mode = 0; /* ????OFF */
/* ?????? */
char_pt = mat01_list;
break;
case 2: /* ???????? */
char_pt = mat02_list;
break;
case 3: /* ?????? */
char_pt = mat03_list;
break;
1997/04/25 G.T.V H.Mizukami */
/*****************************************************************************/
void Item_Mat_Sel(void)
{
int LLpad;
int LLnum = item_sel_mat;
#ifdef DEBUG
FntPrint("item_sel_mat = %d\n", item_sel_mat);
#endif
LLpad = Item_MatMouse();
if(oldpad == PADLup && item_sel_mat)
item_sel_mat--;
if(oldpad == PA if(LLpad == 0 || (oldpad & PADnext))
{
command = 99;
nextcommand = 2;
}
else
{
if((TGPad1 & PADRdown) || Char_cansel())
{
command = 127;
nextcommand = 0;
TGPad1 |= PADnext;
StopPreLoad();
/*******/
void ItemMat(void)
{
int LLpad = 1;
GsBOXF LLbox;
int LLnum = ItemListMatNum[item_sel_mat];
#ifdef DEBUG
FntPrint("sel = %d max = %d\n", ItemListMatNum[item_sel_mat],
ItemListMatMax[item_sel_mat]);
#endif
LLpad = Item_subMatMouse();
if(oldpad == PADLup && ItemListMatNum[item_sel_mat] > 1)
ItemListMatNum[item_sel_mat] -= 2; ItemListMatNum[item_sel_mat] < ItemListMatMax[item_sel_mat] - 1)
ItemListMatNum[item_sel_mat]++;
if(LLnum != ItemListMatNum[item_sel_mat])
{
_mt_sel_snd();
StopPreLoad();
}
if(PreLoad == PL_NOUSE)
ItemSelLoad((long *)(LPKBuf + BG_SZ));
EXsubbox[1].mode = 1;
EXsubbox[1].b & PADRdown) || Char_cansel())
{
command = 127;
nextcommand = 2;
TGPad1 |= PADnext;
StopPreLoad();
}
else
{
if((TGPad1 & PADnext) && LLpad == 0 || (oldpad & PADnext))
{
command = 99;
nextcommand = 3;
/
void Item_Char_SelInit(void)
{
WinFill LLwin;
command = 2;
EXsubbox[0].mode = 0; /* ????OFF */
WinNotDisp(wid[2]);
memset(&LLwin, 0x00, sizeof(WinFill));
LLwin.flag = WINf_GRO;
LLwin.wflag = WINw_001;
LLwin.prm = 5;
wid[3] = WinOpen(&LLwin);
WinSetPos(wid[3], 128, 44, 1 */
/* 1997/03/31 G.T.V H.Mizukami */
/*********************************************************************************************************************************/
static void _init5(SCREEN_JOB *ps, int n)
{
WinFill LLwin;
if(n == -1)
{
ShopList(); /* ????????? */
init_CursolEx(&EXmouse, 0, 256, 120, 32, 22, 3, 3);
memset(&LLwin, 0x00, sizeof(WinFill));
LLwin.flag */
/* */
/* */
/* 1997/03/31 G.T.V H.Mizukami */
/*****************************************************************************/
static void _loop5(S */
MjsLoop(&EXtprm00);
break;
case 1: /* ???????? */
if(How_Kind_PadCon(0) == 1)
SjsSel = 1;
else
SjsSel = 0;
ic_flag = 0;
break;
case 99:
if(anmwait == FsOpen(TOWNFILE);
FsSeek(tmpcmp.lcv_offset+tmpcmp.bg_offset);
FsReadLzs((long*)LPKBuf,tmpcmp.bg_size);
/* Miz*/
FsOpen(tmpcmp.lpkname);
FsSeek(tmpcmp.bg_offset);
FsReadLzs((long*)LPKBuf,tmpcmp.bg_size);
/**/
PreLoad=PL_USENOW;
/* 1997/03/31 G.T.V H.Mizukami */
/*****************************************************************************/
static int _before5(SCREEN_JOB *ps, int n)
{
if(command == 0)
return(1);
command--;
return(0);
}
/***********************/
raw();
}
}
/*****************************************************************************/
/* ???? */
/* **********/
/* ???????????? */
/* */
/* ***************************************************************/
/* ?????????? */
/**************************************/
CR_NOTPUSH,
_sinit5,
_init5,
_loop5,
NULL,
NULL,
NULL,
_draw5,
_end5,
wp,
{NULL,},
512, 240,
NULL, 0,
NULL,
0,
1,
};
/************** */
/* */
command = 0;
Shop_Sel = 0;
SjsSel = 0;
SjsSetBeforeKey(NULL);
}
anmwait = 0;
}
/**************************************************/
;
#endif
oldx = EXmouse.cx;
oldy = EXmouse.cy;
oldpad = TGPad1;
if(How_Kind_PadCon(0) == 1)
read_Mouse_Data(&EXmouse, 1);
SjsSel = 1;
switch(command)
{
StopPreLoad();
SetTim(LPKBuf, 512, 0, 0, 480);
_mt_ok_snd();
anmwait = 0;
SjsSel=0;
SjsSetMode(&scr_list);
return;
}
}
else
{
command--;
_t_cancel_snd();
}
}
}
/*****************************************************************************/
/*******************************************************************/
static void _init5(SCREEN_JOB *ps, int n)
{
WinFill LLwin;
if(n == -1)
{
ShopList(); /* ????????? */
init_CursolEx(&EXmouse, 0, 256, 120, 32, 22, 3, 3);
memset(&LLwin, 0x00, sizeof(WinFill));
LLwin.flag */
/* */
/* 1997/03/31 G.T.V H.Mizukami */
/*****************************************************************************/
static void _loop5(Swait ==
h>
/**************************************************************************/
#include "ff.h"
//#include "ff7list.h"
#include "winsys.h"
#include "cursol.h"
#include "datafanm.inc"
#include "dataflpk.inc"
#include "lpk_sys.inc"
#include "ffaku.h"
#include "clickm.h"
#include "npk_item.inc"
/*****************************************************************************/
/* ??? GAMEN_X 168 /* ???X?? */
#define ZIGAMEN_X 282 /* ???X?? */
#define ZIGAMEN_Y 1O???? */
static int oldpad; /* ????????? ?? */
static char ************************************/
void Item_opSel(void); /* ?????????7 G.T.V H.Mizukami */
/****************************
*/
= 1;
LLbox.g = 1;
LLbox.b = 1;
LLbox.x = 16-256;
LLbox.y = 20-120;
LLbox.w = 332;
LLbox.h = 16;
GsSortLLtbl[Q1];
if(i < 0)
{
ListPage[Q1] = n + 0x30;
i = i + LLtbl[Q1];
/* */
/* 1997/03/26 G.T.V H.Mizukami */
/******************** /* ?????? */ */
strcat(mlistbuf, akuselist[LLtop + Q1]);
break;
case 4: /* ??? */
strcat(mli */
/* 1997/04/22 G.T.V H.Mizukami */
/*****************************************************************************/
void Item_SelMenuInit(void)
{
WinFill LLwin;
????????? */
case 4: /* ?????? */
ListInit(item_menu);
WinSetPos(wid[2], 128, 44, 16*20, 14*10);
WinSetRGB(wid[2], 0, 0, 255, RGB_BUL);
break;
**********************************************************************/
void Item_SelMenu(void)
{
int LLnum;
MjsLoop(&EXtprm01);
if((LLnum = MjsMenuStat(&EXtprm01)) == -1)
return;
/*se 1997/04/25 G.T.V H.Mizukami */
/*****************************************************************************/
void Item_Mat_SelInit(void)
{
WinFill LLwin;
command = 2;
EXsubbox[0].mode = 0; /* ????OFF at01_list;
break;
case 2: /* ???????? */
char_pt = mat02_list;
break;
case 3: /* ?????? */
char_pt = mat03_list;
break;
/* 1997/04/25 G.T.V H.Mizukami */
/*****************************************************************************/
void Item_Mat_Sel(void)
{
int LLpad;
int LLnum = item_sel_mat;
#ifdef DEBUG
FntPrint("item_sel_mat = %d\n", item_sel_mat);
#endif
LLpad = Item_MatMouse();
if(oldpad == PADLup && item_sel_mat)
item_sel_mat--;
if(oldpad == PA if(LLpad == 0 || (oldpad & PADnext))
{
command = 99;
nextcommand = 2;
}
else
{
if((TGPad1 & PADRdown) || Char_cansel())
{
command = 127;
nextcommand = 0;
TGPad1 |= PADnext;
StopPreLoad();
void ItemMat(void)
{
int LLpad = 1;
GsBOXF LLbox;
int LLnum = ItemListMatNum[item_sel_mat];
#ifdef DEBUG
FntPrint("sel = %d max = %d\n", ItemListMatNum[item_sel_mat],
ItemListMatMax[item_sel_mat]);
#endif
LLpad = Item_subMatMouse();
if(oldpad == PADLup && ItemListMatNum[item_sel_mat] > 1)
ItemListMatNum[item_sel_mat] -= 2; ItemListMatNum[item_sel_mat] < ItemListMatMax[item_sel_mat] - 1)
ItemListMatNum[item_sel_mat]++;
if(LLnum != ItemListMatNum[item_sel_mat])
{
_mt_sel_snd();
StopPreLoad();
}
if(PreLoad == PL_NOUSE)
ItemSelLoad((long *)(LPKBuf + BG_SZ));
EXsubbox[1].mode = 1;
EXsubbox[1].b & PADRdown) || Char_cansel())
{
command = 127;
nextcommand = 2;
TGPad1 |= PADnext;
StopPreLoad();
}
else
{
if((TGPad1 & PADnext) && LLpad == 0 || (oldpad & PADnext))
{
command = 99;
nextcommand = 3;
/
void Item_Char_SelInit(void)
{
WinFill LLwin;
command = 2;
EXsubbox[0].mode = 0; /* ????OFF */
WinNotDisp(wid[2]);
memset(&LLwin, 0x00, sizeof(WinFill));
LLwin.flag = WINf_GRO;
LLwin.wflag = WINw_001;
LLwin.prm = 5;
wid[3] = WinOpen(&LLwin);
WinSetPos(wid[3], 128, 44, 1 case 3: /* ???13??? */
char_pt = char03_list;
break;
case 4: /* ??????? */
char_pt = char04_list;
break;
case 5: /* ????? */
char_pt = char05_listNum[item+ 1 >=
BAEMax[item_menu])
bak = 1;
else
{
bak = BAENum[item_menu];
BAENum[item_menu]++;
ItemSelLoad((long *)MODELBuf);
BAENum[item_menu] = bak;
bak = ItemListNum[item_sel_hero];
break;
case 1: /* ?? */
SjsSel = 0;
switch(item_menu)
dispcom = 99;
dispcom = 99;
DEBUG
FntPrint("mat sel = %d\n", ItemListMatNum[item_sode(&scr_item_disp);
oid cu_l(ANM2D *a2, ANMOBJ *ao)
{
ao->wait = 1;
if(dispcom == 99 || wait)
return;
if(item_menu != 0 && item_menu != 3)
/* ??????????????? */
/* */
if(ItemListMatNum[item_sel_mat] <
ItemListMatMax[item_sel_mat] - 1)
{
ao->wait = 0;
ao->Move(ao, 1);
/*****************************************************************************/
/* ?????????? */
/*****************************************************************************/
static ANM2D anm2[L,
wp2,
{NULL,},
512, 240,
NULL, 0,
NULL,
0,
1,
};
/*****************************************************************************/
/* ??????????????????????????? */
/*
};
/*****************************************************************************/
/* ??????? */
/*****************************************************************************/
static WIPE_PRM wp3[] = {
{&WjCinCout,16,itch(EXdatflag)
{
case 0: /* ?? */
*AGoffset = BukSZTBL[EXdatnum].offset;
*AGsize = BukSZTBL[EXdatnum].size;
: /* ???? */
*AGoffset = MatSZTBL[EXdatnum].offset;
*AGsize = MatSZTBL[EXdatnum].size;
strcpy(LLbuf, "ITEM\\MATER\\MATER.FFD");
break;
/* 1997/03/28 G.T.V */
/*****************************************************************************/
static void _sinit3(SCREEN_JOB *ps, int n)
{
char LLbuf[64];
int i, Q1;
int LLnum, LLoffset, LLsize;
if(n == -py(LLbuf, Item_Image_TBL01[i]);
break;
case 2: // ??????
LLoffset = AkuSZTBL[EXdatnum].offset;
LLsize = AkuSZTBL[EXdatnum].size;
strcpy(LLbuf, Item_Image_TBL02[i]);
break;
case 3: // ????
dSync(0);
break;
case PL_DONE:
break;
case PL_NOUSE:
case PL_MUSTNOT:
default:
select_gfile(LLbuf, &LLoffset, &LLsize);
FsOpen(LLbuf);
FsSeek(LLoffset);
FsReadLzsB((long*)LPKBuf, */
/* */
/* 1997/03/28 G.T.V */
/*****************************************************************************/
static void _init3(SCREEN_JOB *ps, int n)
{
SjsSel = 0;
wait = 4;
Sjs */
/*****************************************************************************/
static void _loop3(SCREEN_JOB *ps)
{
ClickMap tmpcmp; // ????TEMP?????????
if(!PreLoad)
{
StopPreLoad();
tmpcmp=town_cmp[j_sel];
FsOpen(TOWNFILE);
FsSeek(tmpcmp.lcv_offset+tmpcmp.b
/* *****************************************************************/
/* ???? */
/* */
/* */
/* */
56|SCR_NOTPUSH,
_sinit3,
_init3,
_loop3,
NULL,
NULL,
NULL,
NULL,
_s_end,
wp3,
{&WjCinCout,64,0,0,0},
512, 240,
NULL, 0,
NULL,
0,
1,
};
/*****************************************************************************/
/* ????(????????)?? */
el < list_tbl_num - 1)
Shop_Sel++;
if(LLnum != Shop_Sel)
{
_mt_sel_snd();
StopPreLoad();
}
if(PreLoad == PL_NOUSE)
{
switch(list_tbl[Shop_Sel].f)
{
case 0:
for(Q1 = 0, i = 0; Q1 < list_tbl[Shop_Sel].n0; Q1++)
*************************************************************************/
#include "ff.h"
#include "ff7list.h"
#include "winsys.h"
#include "cursol.h"
#include "datafanm.inc"
#include "dataflpk.inc"
#include "lpk_sys.inc"
#include "ffaku.h"
#include "clickm.h"
#include "npk_item.inc"
/*****************************************************************************/
/* ??? */
Buf, (long *)ComnBuf
#define DEFSYS LZ_TIM | LZ_CLUT, (long *)SYSBuf, (long *)ComnBuf
#define SUBBERMAX 3
#define SUBBERMAX 3
#define ZENGAMEN_X 168 /* ???X?? */
#define ZIGAMEN_X 282 /* ???X?? */
#define ZIGAMEN_Y 15 /* ???? */
static int oldx; /* ???X??????? */
static int oldy; /* ???Y??????? */
static int oldpad; /* ????????? ???? */
int EXdatnum; /* ?? */
static char EXe????**********tBo[Q1];
*********cat(mlist set_ c== PADLmat] -= 2;
rt;
if(How_Kind_PadCon(0) == 4) /* ???????? */
{
set_Cursol_Point */
/* 1997/03/26 G.T.V H.Mizukami */
/****/
if(oldpad == PADLup && LLsel > 1)
BAENum[item_menu] -= 2;
if(oldpad == PADLdown && LLsel < LLend - 2)
BAENum[item_menu] += 2;
if(oldpad == PADLleft && LLsel % 2)
BAENum[item_menu]--;
if(oldpad == PADLright && (LLsel % 2) == 0 && LLsel < LLend - 1)
BAENum[item_menu]++;
if(LLnum != BAENum[item_me set_Cursol_Point(&EXmouse, ZENGAMEN_X, ZIGAMEN_Y);
}
StopPreLoad();
return;
}
if((((EXmouse.cx > 250 && EXmouse.cy > 10 &&
EXmouse.cx < 300 && EXmouse.cy < 22) &&
(TGPad1 & PADnext)) || (oldpad == PADR1)) && LLend == 20 &&
LLtop + 20 != BAEMax[item_menu])
{
1;
EXsubbox[0].ber.attribute = 0;
EXsubbox[0].ber.r = 0;
EXsubbox[0].ber.g = 128;
EXsubbox[0].ber.b = 0;
EXsubbox[0].ber.x = LLsel % 2 * 161 + 122+8 - 256;
EXsubbox[0].ber.y = LLsel / 2 * 14 + 44 - 120;
EXsubbox[0].ber.w = 156;
EXsubbox[0].ber.h = 14;
if(How_Kind_PadCon(0) == 4)
{
set_Curtprm03);
}
/*****************************************************************************/
/* ??????? */
/* */
/* */
/* */
ItemListMax[item_sel_hero] - 2)
{
ItemListNum[item_sel_hero] += 2;
if(ItemListNum[item_sel_hero] >= ItemListMax[item_sel_hero])
ItemListNum[item_sel_hero] =
ItemListMax[item_sel_hero] - 1;
}
if(oldpad == PADLleft && ItemListNum[item_sel_hero] % 2)
*/
/* */
/* */
/* 1997/03/31 G.T.V H.Mizukami */
/*********************************************************************** */1;
else
SjsSel = 0;
ic_flag = 0;
break;
case 99:
_;
/
/* ******
******/
/* ??? */
MjsLown && ItemLa 20char05_list;
t_Cursol_Point(&***u
},
{_O_AKU04_FFD, _S_AKU04_FFD},
{_O_AKU05_FFD, _S_AKU05_FFD},
{_O_AKU06_FFD, _S_AKU06_FFD},
};
PFileDat Npk_BouSZTBL[] = {{_O_BOUGU00_FFD, _S_BOUGU00_FFD},
{_O_BOUGU01_FFD, _S_BOUGU01_FFD},
UKI09_FFD, _S_BUKI09_FFD},
{_O_BUKI10_FFD, _S_BUKI00_FFD},
{_O_BUKI11_FFD, _S_BUKI11_FFD},
#define _S_GUA_021_TIM 56566
#define _O_GUA_022_TIM 0xe000
#define _S_GUA_022_TIM 67549
#define _O_GUA_023_TIM 0x1e800
#define _S_GUA_023_TIM 61491
#define _O_GUA_024_TIM 0x2e000
#define _S_GUA_024_TIM 67618
#define _O_GUA_025_TIM 0x3f000
#define _S_GUA_025_TIM 68968
#define _BOUGU04_FFD_SIZE 327680
/*** [EOF] ***/
/*** NPK Header File ***/
#define _O_GUA_02
К сожалению, не доступен сервер mySQL