Halusin päästä käsiksi kuvien pikselidataan suoraan CoolBasicin puolelta, ihan ilman PutPixelin käyttöä. Tämä vaatisi kuitenkin kirjoittelun mielivaltaisiin muistiosoitteisiin, jota CB ei varsinaisesti tue.
Ongelma kuitenkin helpottuu, jos huomaamme että CB:n muistipalat ovatkin oikeastaan vain bbBank-tietueita, joiden määritelmä on seuraava:
Code: Select all
struct bbBank {
int paske; // Only in CoolBasic implementation, extra info for VM?
char *data; // MemBlock data, this is visible to the programmer.
int size, capacity;
};
Nyt voimme vielä huomata, että CoolBasicin MEMBlockSize-komento kutsuu Blitzin runtimen bbBankSize-funktiota, joka on koodissa määritelty seuraavasti:
Code: Select all
int bbBankSize( bbBank *b ){
return b->size;
}
Code: Select all
blok = MakeMemBlock(8)
addr = MemBlockSize(blok - 4) // Returns m->data pointer!
Nyt voimme kirjoittaa arvon X osoiteeseen A.
Code: Select all
pokeInt blok, 4, A
addr = MEMBlockSize(blok - 4)
PokeInt addr, 0, X
Code: Select all
global proxyblock
proxyblock = makeMEMBlock(8) // this acts as a bbBank*
function write_int(addr, ofs, value)
pokeInt proxyblock, 4, addr // ((bbBank*)proxyblock)->data = addr;
pokeInt MEMBlockSize(proxyblock-4), ofs , value // ((bbBank*)proxyblock->data)[ofs] = value
endFunction
Kuvat
Pitkän räpellyksen oman DLL:n ja Visual Studion debuggerin kanssa sain vihdoin selviteltyä miten kuvadata on tallennettu. Eipä siinä mitään kovin erikoista sitten ollutkaan. Tarkoituksena on siis löytää osoitin, johon kirjoittamalla saamme piirreltyä pikseleitä ruudulle.
CoolBasicin kuvat ovat seuraavaa muotoa:
Code: Select all
struct CBImage {
int useless_data;
bbImage img;
};
Code: Select all
struct CBImage {
int useless_data;
std::vector<gxCanvas*> frames;
};
Code: Select all
struct CBImage {
int useless_data;
gxCanvas** canvas;
};
Code: Select all
void setPixelFast( int x,int y,unsigned argb ){
format.setPixel( locked_surf+y*locked_pitch+x*format.getPitch(),argb );
++mod_cnt;
}
Alla on listattu gxCanvas-tietueen määritelmä.
Code: Select all
class gxCanvas{
private:
int flags,cube_mode;
gxGraphics *graphics;
ddSurf *main_surf,*surf,*z_surf,*cube_surfs[6];
mutable int mod_cnt;
mutable ddSurf *t_surf;
mutable int locked_pitch,locked_cnt,lock_mod_cnt,remip_cnt;
mutable unsigned char *locked_surf;
mutable int cm_pitch;
mutable unsigned *cm_mask;
RECT clip_rect;
PixelFormat format;
gxFont *font;
RECT viewport;
int origin_x,origin_y,handle_x,handle_y;
unsigned mask_surf,color_surf,color_argb,clsColor_surf;
}

Generoitu kuva näyttää tältä.
Code: Select all
clsColor 64,64,64
cls
global proxyblock
proxyblock = makeMEMBlock(8) // this acts as a bbBank*
function write_int(addr, ofs, value)
pokeInt proxyblock, 4, addr // ((int*)proxyblock->data)[1] = addr;
pokeInt MEMBlockSize(proxyblock-4), ofs , value // ((bbBank*)proxyblock->data)[ofs] = value
endFunction
function read_int(addr, ofs)
pokeInt proxyblock, 4, addr // ((int*)proxyblock->data)[1] = addr;
return peekInt (MEMBlockSize(proxyblock-4), ofs) // return ((bbBank*)proxyblock->data)->data[ofs];
endFunction
m = makeMEMBlock(8)
write_int(m,8,3) // we can overwrite memblock->size, for example
addText ""+read_int(m, 8)
img = makeImage(200, 200)
maskImage img, 255,0,255
// struct CBImage {
// int useless_data;
// gxCanvas** canvas;
// };
//struct gxCanvas {
// int flags, cube_mode;
// gxGraphics *graphics;
//
// ddSurf *main_surf, *surf, *z_surf, *cube_surfs[6];
//
// int mod_cnt;
// ddSurf *t_surf;
//
// int locked_pitch, locked_cnt, lock_mod_cnt, remip_cnt;
// unsigned char *locked_surf; <-- we want this!
//
// int cm_pitch;
// unsigned *cm_mask;
//
// RECT clip_rect;
//
// PixelFormat format;
//
// gxFont *font;
// RECT viewport;
// int origin_x, origin_y, handle_x, handle_y;
// unsigned mask_surf, color_surf, color_argb, clsColor_surf;
//};
lock image(img)
canvas_pp = read_int(img, 4)
canvas_p = read_int(canvas_pp, 0)
locked_surf = read_int(canvas_p, 18*4)
// typedef struct tagRECT {
// LONG left; LONG top; LONG right; LONG bottom;} RECT;
w = read_int(canvas_p, (21 + 2)*4)
h = read_int(canvas_p, (21 + 3)*4)
locked_pitch = read_int(canvas_p, (14)*4)
addText "pitch: " + locked_pitch
for y = 0 to h-1
for x = 0 to w-1
write_int(locked_surf, y*locked_pitch + x*4, x + (y shl 8))
next x
next y
unlock image(img)
addText "width: " + w
addText "height: " + h
drawImage img, 100, 50
drawScreen
waitKey
