#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "greenland.h"
#include "files.h"
//#include "save.h"
static void saveImg(GtkWidget *w,gpointer data);
static GtkItemFactoryEntry menuItems[]={
{ "/_Save Image", NULL, saveImg, 0, NULL},
};
static GtkWidget *statusbar;
static dword chunkOffset;
static GtkWidget *draw;
static ResFile *res;
static dword frameNum,saveFrameNum;
static dword realX,realY,realW,realH;
static dword framewidth,frameheight;
static word width,height;
static GdkPixbuf *screen=NULL;
static byte *surface,*surface2;
static byte updateScreen;
static byte palette[256*3];
static gboolean readChunk();
static void initVideo();
static void saveFrame(word wc);
static void decodeBlocks(byte *in2,byte *in,word x,word y,word w,word h);
static void saveImg(GtkWidget *w,gpointer data)
{
}
static gint popup(GtkWidget *widget,GdkEvent *event)
{
if (event->type==GDK_BUTTON_PRESS)
{
GdkEventButton *bevent=(GdkEventButton *)event;
if (bevent->button==3)
gtk_menu_popup(GTK_MENU(widget),NULL,NULL,NULL,NULL,
bevent->button,bevent->time);
return TRUE;
}
return FALSE;
}
static gint drawImage(GtkWidget *widget,GdkEventExpose *event,gpointer data)
{
int w,h;
if (!screen) return TRUE;
w=gdk_pixbuf_get_width(screen);
h=gdk_pixbuf_get_height(screen);
gdk_pixbuf_render_to_drawable(screen,widget->window,widget->style->fg_gc[GTK_STATE_NORMAL],0,0,0,0,w,h,GDK_RGB_DITHER_NONE,0,0);
return TRUE;
}
static void handleChunk(byte *in,dword size)
{
dword offset,i;
word packetSize;
byte *ptr,*ptr2,opcode,param;
word wa,wb,wc,wd;
dword da,db,delay,delaydiv;
ptr2=NULL;
offset=0;
ptr=in;
do {
packetSize=*(word*)ptr;
opcode=ptr[2];
param=ptr[3];
ptr+=4;
switch (opcode)
{
case 0: return;
case 1: return;
case 2: //movie timing
da=*(dword *)(ptr);
wb=*(word *)(ptr+4);
delaydiv=1000/wb;
delay=da/delaydiv;
g_timeout_add(delay,readChunk,NULL);
break;
case 3: //init sound
break;
case 4: //play sound
break;
case 5: //init video
framewidth=(*(word *)ptr)<<3;
frameheight=(*(word *)(ptr+2))<<3;
initVideo();
break;
case 7: // show frame
wa=*(word *)ptr;
wb=*(word *)(ptr+2);
wc=0;
if (param>0) wc=*(word *)(ptr+4);
saveFrame(wc);
updateScreen=1;
break;
case 8: // sound data
break;
case 9: // sound control
break;
case 10: // init movie
width=*(word*)ptr;
height=*(word*)(ptr+2);
break;
case 12: // set palette
wa=*(word*)ptr;
wb=*(word*)(ptr+2);
memcpy(palette+wa*3,ptr+4,wb*3);
break;
case 15: // decoder control
ptr2=ptr;
break;
case 17: // decode blcoks
wa=*(word *)(ptr+4);
wb=*(word *)(ptr+6);
wc=*(word *)(ptr+8);
wd=*(word *)(ptr+10);
if (ptr[12]&1)
{
byte *temp;
temp=surface2;
surface2=surface;
surface=temp;
}
decodeBlocks(ptr2,&ptr[14],wa,wb,wc,wd);
break;
case 19: //unknown
case 21:
break;
default:
printf("Unknown opcode %x\n",opcode);
exit(1);
}
ptr+=packetSize;
offset+=packetSize;
} while (offset<size);
}
static void initVideo()
{
surface=(byte *)calloc(framewidth*frameheight,1);
surface2=(byte *)calloc(framewidth*frameheight,1);
if (screen)
gdk_pixbuf_unref(screen);
screen=gdk_pixbuf_new(GDK_COLORSPACE_RGB,FALSE,8,framewidth,frameheight);
gtk_widget_set_usize(draw,framewidth,frameheight);
}
static void saveFrame(word wc)
{
int x,y;
byte *source,*dest,*sdata,*sptr,val,r,g,b;
long rowstride;
source=surface;
source+=(realY*framewidth)+realX;
rowstride=gdk_pixbuf_get_rowstride(screen);
dest=gdk_pixbuf_get_pixels(screen);
dest+=(realY*rowstride)+realX;
for (y=0;y<realH;y++)
{
sdata=dest;
sptr=source;
for (x=0;x<realW;x++)
{
val=*sptr++;
*sdata++=palette[val*3]<<2;
*sdata++=palette[val*3+1]<<2;
*sdata++=palette[val*3+2]<<2;
}
dest+=rowstride;
source+=framewidth;
}
gdk_pixbuf_render_to_drawable(screen,draw->window,draw->style->fg_gc[GTK_STATE_NORMAL],realX,realY,realX,realY,realW,realH,GDK_RGB_DITHER_NONE,0,0);
frameNum++;
}
static byte *sameBlock(byte *source,byte *dest)
{
int y;
byte *ptr;
dword delta;
delta=dest-surface;
ptr=surface2+delta;
for (y=0;y<8;y++)
{
memcpy(dest,ptr,8);
dest+=framewidth;
ptr+=framewidth;
}
return source;
}
static byte *copyPreBlock(byte *source,byte *dest)
{
int y;
byte *ptr,val;
char hi,lo;
long offset;
val=*source++;
if (val>=56)
{
val-=56;
hi=((val/29)+8);
lo=((val%29)-14);
}
else
{
hi=(val/7);
lo=((val%7)+8);
}
offset=lo;
offset+=hi*framewidth;
ptr=dest+offset;
for (y=0;y<8;y++)
{
memcpy(dest,ptr,8);
dest+=framewidth;
ptr+=framewidth;
}
return source;
}
static byte *copyBlock(byte *source,byte *dest)
{
int y;
byte *ptr,val;
char hi,lo;
long offset;
val=*source++;
if (val>=56)
{
val-=56;
hi=-((val/29)+8);
lo=-((val%29)-14);
}
else
{
hi=-(val/7);
lo=-((val%7)+8);
}
offset=lo;
offset+=hi*framewidth;
ptr=dest+offset;
for (y=0;y<8;y++)
{
memcpy(dest,ptr,8);
dest+=framewidth;
ptr+=framewidth;
}
return source;
}
static byte *copyBackBlock(byte *source,byte *dest)
{
int y;
byte *ptr,val;
dword delta;
char hi,lo;
long offset;
val=*source++;
lo=(val&15)-8;
hi=(val>>4)-8;
offset=lo;
offset+=hi*framewidth;
delta=dest-surface;
ptr=surface2+delta+offset;
for (y=0;y<8;y++)
{
memcpy(dest,ptr,8);
dest+=framewidth;
ptr+=framewidth;
}
return source;
}
static byte *shiftBackBlock(byte *source,byte *dest)
{
int y;
byte *ptr;
dword delta;
char hi,lo;
long offset;
lo=*source++;
hi=*source++;
offset=lo;
offset+=hi*framewidth;
delta=dest-surface;
ptr=surface2+delta+offset;
for (y=0;y<8;y++)
{
memcpy(dest,ptr,8);
dest+=framewidth;
ptr+=framewidth;
}
return source;
}
static byte *draw2ColBitBlock(byte *source,byte *dest)
{
int x,y;
byte lo,hi,val;
lo=source[0];
hi=source[1];
if (lo<hi)
{
for (y=0;y<8;y++)
{
val=source[y+2];
for (x=0;x<8;x++)
{
dest[x]=(val&1)?hi:lo;
val>>=1;
}
dest+=framewidth;
}
source+=10;
}
else
{
for (y=0;y<4;y++)
{
if (!(y&1)) val=source[(y/2)+2];
for (x=0;x<4;x++)
{
dest[x*2]=(val&1)?hi:lo;
dest[x*2+1]=dest[x*2];
dest[x*2+framewidth]=dest[x*2];
dest[x*2+1+framewidth]=dest[x*2];
val>>=1;
}
dest+=framewidth*2;
}
source+=4;
}
return source;
}
static byte *draw8ColBitBlock(byte *source,byte *dest)
{
int i,x,y;
byte key,key2,val,hi,lo,hi2,lo2;
lo=source[0];
hi=source[1];
lo2=source[6];
hi2=source[7];
if (lo<hi)
{
for (i=0;i<2;i++)
{
lo=source[i*4];
hi=source[i*4+1];
lo2=source[i*4+8];
hi2=source[i*4+9];
for (y=0;y<4;y++)
{
if (!(y&1)) key=source[y+2+i*4];
for (x=0;x<4;x++)
{
dest[x]=(key&1)?hi:lo;
key>>=1;
}
if (!(y&1)) key2=source[y+10+i*4];
for (x=0;x<4;x++)
{
dest[x+4]=(key2&1)?hi2:lo2;
key2>>=1;
}
dest+=framewidth;
}
}
source+=16;
}
else if (lo2<hi2)
{
for (y=0;y<8;y++)
{
if (!(y&1)) key=source[y+2];
for (x=0;x<4;x++)
{
dest[x]=(key&1)?hi:lo;
key>>=1;
}
if (!(y&1)) key2=source[y+8];
for (x=0;x<4;x++)
{
dest[x+4]=(key2&1)?hi2:lo2;
key2>>=1;
}
dest+=framewidth;
}
source+=12;
}
else
{
for (i=0;i<2;i++)
{
lo=source[i*6];
hi=source[i*6+1];
for (y=0;y<4;y++)
{
key=source[y+2+i*6];
for (x=0;x<8;x++)
{
dest[x]=(key&1)?hi:lo;
key>>=1;
}
dest+=framewidth;
}
}
source+=12;
}
return source;
}
static byte *draw4ColBitBlock(byte *source,byte *dest)
{
int x,y;
byte key,val;
byte cmd[4];
cmd[0]=source[0];
cmd[1]=source[1];
cmd[2]=source[2];
cmd[3]=source[3];
if (cmd[0]<cmd[1] && cmd[2]<cmd[3])
{
for (y=0;y<16;y++)
{
key=source[y+4];
for (x=0;x<4;x++)
{
val=cmd[key&3];
key>>=2;
dest[x+(y&1)*4]=val;
}
if (y&1) dest+=framewidth;
}
sour
没有合适的资源?快使用搜索试试~ 我知道了~
township-开源
2 下载量 148 浏览量
2021-04-26
16:08:45
上传
评论 1
收藏 49KB GZ 举报
温馨提示
共37个文件
c:12个
h:6个
xpm:4个
一套应用程序,用于在许多不同的游戏中查看和编辑数据文件。 例如,《创世纪》,《无限引擎》(鲍德之门,《冰风谷》)和《极光引擎》(《无冬之夜》)。
资源详情
资源评论
资源推荐
收起资源包目录
greenland-0.1.tar.gz (37个子文件)
greenland
autogen.sh 48B
stamp-h 10B
rbmp.c 6KB
rcfile.h 305B
mkinstalldirs
play.xpm 406B
stop.xpm 406B
nextframe.xpm 411B
AUTHORS 0B
config.status 8KB
save.h 341B
COPYING
rplt.c 5KB
aclocal.m4 20KB
INSTALL
rmos.c 6KB
files.c 3KB
rmve.c 16KB
rtis.c 5KB
install-sh
save.c 9KB
Makefile.am 274B
configure 70KB
prefs.c 4KB
missing
config.h 316B
rcfile.c 2KB
Makefile 12KB
config.h.in 237B
NEWS 0B
rwed.c 7KB
stamp-h.in 10B
greenland.c 12KB
Makefile.in 11KB
files.h 606B
greenland.h 1KB
prefs.h 107B
README 167B
configure.in 560B
rbam.c 16KB
ChangeLog 0B
prevframe.xpm 411B
共 37 条
- 1
mckaywrigley
- 粉丝: 30
- 资源: 4718
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0