中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS汉化世界 & 中文系统 (中文化室) » UCDOS 5.0 版本以上曲线字库汉字显示程序源代码
English/Chinese Fix Translation
作者:
标题: UCDOS 5.0 版本以上曲线字库汉字显示程序源代码 上一主题 | 下一主题
lhsong
初级用户





积分 47
发帖 12
注册 2008-9-5
状态 离线
『楼 主』:  UCDOS 5.0 版本以上曲线字库汉字显示程序源代码 使用 LLM 解释/回答一下

若字库为5.0版,应去掉下面一段代码

if(j==1){ //若为汉字,调整地址偏移值
hz.offset-=0x10000000;
}


希望大家能够喜欢!!!!!!!


#include "d:\borland\user\src\graphics.h"
#include "d:\borland\user\src\graphics.c"

#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <mem.h>
#include <alloc.h>
#include <dir.h>
#include <dos.h>
#include <stdlib.h>
#define baseSize 250 //此值越大,字体越小,原值为168
#define portion 100 //100

FILE *fpfh,*fphz,*fpe,*fp;


int X0,Y0,xRange,yRange,curX,curY;
int newX0,newY0,newxRange,newyRange;
unsigned char *wordCont_0=NULL,*wordCont_8=NULL;
unsigned bytesNum_0,bytesNum_8;
unsigned char myread(void);
void control(int *xx,int *yy,unsigned char controlWord,int nowxRange,
int nowyRange,int nowX0,int nowY0,int call_8_0);
void showhz(char *fontfileName,unsigned long col);
void b3_4(int *x,int *y,unsigned long col);
void b3_3(int *x,int *y,unsigned long col);

int readbyte(void);

int readcount;
static unsigned char next; //用于读取字节高四位、低四位的标志,1读高位,0读低位

typedef struct _hz{
unsigned long offset; //4字节
unsigned int length; //2字节
}hz_;
hz_ hz;

unsigned char hzdata; //用于读取字型数据



void main(void)
{

unsigned char *hzstring="然字Mm骤啊H骤g9酆8G字,汉,然。!!戆";//戆您原回骤然燃";//"共有汉字个骤";原骤戆啊汉字

long color;

initgraph(VBE480_16M);

X0=Y0=1;xRange=yRange=152;//原值为152
showhz(hzstring,rgbcolor(255,0,0));

getch();
cleardevice();
closegraph();
}

void showhz(char *hzstring,unsigned long col)
{
unsigned long oldcolor;
unsigned long wordOffset;
unsigned char qm,wm;
int bx,by; //用于记录笔画的起始点坐标
int xx,yy,controlWord,i,j,m=0;
char ch,cha,chx,chy,chxx,chyy;
char mark1_x,mark1_y,mark2_x,mark2_y,mark3_x,mark3_y;
char *fontFileName="HZKPSKTJ";//HZKPSXKJ";//HZKPSST.GBK";//"HZKPSHTJ";//"HZKPSFSJ";//"HZKPSXBJ";HZKPSKTJ;HZKPSY3J;ASCPS;HZKPST;HZKPSDHJ,HZKPSYTJ
oldcolor=getcolor();
setcolor(col);
if((fpfh=fopen("HZKPST","rb"))==NULL) { //打开中文符号曲线字库
printf("Cannot open %s file\n","HZKPST");
exit(0);
}
if((fphz=fopen(fontFileName,"rb"))==NULL) { //打开中文曲线字库,若为GBK字库,则打开的是GBK字库
printf("Cannot open %s file\n",fontFileName);
exit(0);
}
if((fpe=fopen("ASCPS","rb"))==NULL) { //打开英文曲线字库
printf("Cannot open %s file\n","ASCPS");
exit(0);
}
i=0;
while(i<strlen(hzstring))
{
readcount=0;
next=0;
if((hzstring&0x80)==0x80){ //判断是否为汉字,相等,即最高位是1,则为汉字
qm=hzstring-0xa0; //区码
wm=hzstring-0xa0; //位码
j=1; //作为汉字的标志,用于调整地址偏移
if(strcmp(strrchr(fontFileName, '.')+1,"GBK")==0){ //首先找到最后一个'.'的位置,加1使指针指向'.'后的第一个字符,然后进行比较,判断是否是GBK字库
fp=fphz; //GBK字库仍有部分汉字缺失,如“镕”字,在字库中不存在
wordOffset=(((long)qm-1)*94+(wm-1))*6; //GBK字库已包含了16区以前的汉字符号字库,计算地址时,区码应减去1,而不是减去6
}
else { //不是GBK字库
if(qm>=16){ //16区以后的汉字
fp=fphz;
wordOffset=(((long)qm-16)*94+(wm-1))*6; //16区以后的汉字偏移
}
else{ //16区以前的汉字符号
fp=fpfh;
wordOffset=(((long)qm-1)*94+(wm-1))*6; //16区以前的汉字符号偏移
}
}
i+=2; //汉字为两字节
}
else{ //是英文字符
fp=fpe;
wordOffset=(0*94+(hzstring-32)-1)*6; //英文字体共有十种0~9,设字体号为N,字符ASCII码为CC,则英文字符偏移为(N*94+(CC-32)-1)*6,空格的ASCII码值为32,但在字库中不存在,字库的起始字符是'!'号,值为33,实际应减33,字库中每种字体字符数为94个
i+=1;
}

fseek(fp,wordOffset,SEEK_SET);
fread(&hz,sizeof(hz_),1,fp);
if(j==1){ //若为汉字,调整地址偏移值
hz.offset-=0x10000000;
j=0;
}
fseek(fp,hz.offset,SEEK_SET);
fread(hzdata,1,hz.length,fp);
while(readcount<hz.length) {
ch=myread(); //取控制码
switch(ch){
case 0: //新起点 0000
if(readcount>0)lineto(bx,by); //整个字的第一个起点时不连接,将笔画的最后一个点与起始点相连,将笔画封闭
xx=readbyte();
yy=readbyte();
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
xx+=X0;yy+=Y0;
moveto(xx,yy); //笔画起点
curX=xx;curY=yy;
bx=xx;by=yy; //记录笔画的起始点坐标
break;

case 1:
xx=readbyte();
xx=xRange*xx/baseSize+0.5;
xx+=X0;
lineto(xx,curY);
curX=xx;
break;

case 2:
yy=readbyte();
yy=yRange*yy/baseSize+0.5;
yy+=Y0;
lineto(curX,yy);
curY=yy;
break;

case 3:
xx=readbyte();
yy=readbyte();
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
xx+=X0;yy+=Y0;
lineto(xx,yy);
curX=xx;curY=yy;
break;

case 4:
xx=curX;yy=curY;
xx=readbyte();
yy=readbyte();
xx=readbyte();
yy=readbyte();
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
xx+=X0;yy+=Y0;
xx+=X0;yy+=Y0;
b3_3(xx,yy,COLOR);
curX=xx;curY=yy;
moveto(curX,curY);
break;

case 5:
xx=curX;yy=curY;
xx=readbyte();
yy=readbyte();
xx=readbyte();
yy=readbyte();
xx=readbyte();
yy=readbyte();
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
for(m=1;m<4;m++) {
xx+=X0;yy+=Y0;
}
b3_4(xx,yy,COLOR);
curX=xx;curY=yy;
moveto(curX,curY);
break;

case 6:
xx=readbyte();
yy=readbyte();
xx=readbyte();
yy=readbyte();
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
xx=xRange*xx/baseSize+0.5;
yy=yRange*yy/baseSize+0.5;
for(m=0;m<2;m++) {
xx+=X0;yy+=Y0;
}
rectangle(xx,yy,xx,yy);
break;

case 7:
mark1_x=1;
ch=myread();
if(ch&8)mark1_x=-1;
ch&=7;
xx=curX+ch*mark1_x*xRange/baseSize+0.5;
yy=readbyte();
yy=yRange*yy/baseSize+0.5;
yy+=Y0;
lineto(xx,yy);
curX=xx;curY=yy;
break;

case 8:
mark1_y=1;
xx=readbyte();
xx=xRange*xx/baseSize+0.5;
xx+=X0;
ch=myread();
if(ch&8)mark1_y=-1;
ch&=7;
yy=curY+ch*mark1_y*yRange/baseSize+0.5;
lineto(xx,yy);
curX=xx;curY=yy;
break;

case 9:
mark1_x=1;
mark1_y=1;
ch=myread();
if(ch&8)mark1_x=-1;
ch&=7;
xx=curX+ch*mark1_x*xRange/baseSize+0.5;
ch=myread();
if(ch&8)mark1_y=-1;
ch&=7;
yy=curY+ch*mark1_y*yRange/baseSize+0.5;
lineto(xx,yy);
curX=xx;curY=yy;
break;

case 10:
mark1_x=1;
mark1_y=1;
ch=myread(); //第一次读取的四位作为六位数据的高四位
cha=myread(); //第二次读取的四位的高两位作为六位数据的低两位,低两位作为第二个六位数的高两位
ch=(ch<<2)+(cha>>2);
if(ch&0x20)mark1_x=-1;
ch&=0x1f;
xx=curX+ch*mark1_x*xRange/baseSize+0.5;
ch=myread(); //第三次读取的四位作为第二个六位数的低四位
ch=((cha&0x03)<<4)+ch;
if(ch&0x20)mark1_y=-1;
ch&=0x1f;
yy=curY+ch*mark1_y*yRange/baseSize+0.5;
lineto(xx,yy);
curX=xx;curY=yy;
break;

case 11:
mark1_x=1;
mark1_y=1;
mark2_x=1;
mark2_y=1;
xx=curX;yy=curY;
ch=myread();
if(ch&8)mark1_x=-1;
chx=ch=(ch&7)*mark1_x;
xx=curX+ch*xRange/baseSize+0.5;

ch=myread();
if(ch&8)mark1_y=-1;
chy=ch=(ch&7)*mark1_y;
yy=curY+ch*yRange/baseSize+0.5;

ch=myread();
if(ch&8)mark2_x=-1;
ch=(ch&7)*mark2_x;
xx=curX+(chx+ch)*xRange/baseSize+0.5;

ch=myread();
if(ch&8)mark2_y=-1;
ch=(ch&7)*mark2_y;
yy=curY+(chy+ch)*yRange/baseSize+0.5;

b3_3(xx,yy,COLOR);
curX=xx;curY=yy;
moveto(curX,curY);
break;

case 12:
mark1_x=1;
mark1_y=1;
mark2_x=1;
mark2_y=1;

xx=curX;yy=curY;
ch=myread(); //1
cha=myread(); //2
ch=(ch<<2)+(cha>>2);
if(ch&0x20)mark1_x=-1;
chx=ch=(ch&0x1f)*mark1_x;
xx=curX+ch*xRange/baseSize+0.5;

ch=myread(); //3
ch=((cha&0x03)<<4)+ch;

if(ch&0x20)mark1_y=-1;
chy=ch=(ch&0x1f)*mark1_y;
yy=curY+ch*yRange/baseSize+0.5;

ch=myread(); //1
cha=myread(); //2
ch=(ch<<2)+(cha>>2);
if(ch&0x20)mark2_x=-1;
ch=(ch&0x1f)*mark2_x;
xx=curX+(chx+ch)*xRange/baseSize+0.5;

ch=myread(); //3
ch=((cha&0x3)<<4)+ch;
if(ch&0x20)mark2_y=-1;
ch=(ch&0x1f)*mark2_y;
yy=curY+(chy+ch)*yRange/baseSize+0.5;
b3_3(xx,yy,COLOR);
curX=xx;curY=yy;
moveto(curX,curY);
break;

case 13:
mark1_x=1;
mark1_y=1;
mark2_x=1;
mark2_y=1;
mark3_x=1;
mark3_y=1;
xx=curX;yy=curY;
ch=myread();
if(ch&8)mark1_x=-1;
chx=ch=(ch&7)*mark1_x;
xx=curX+ch*xRange/baseSize+0.5;

ch=myread();
if(ch&8)mark1_y=-1;
chy=ch=(ch&7)*mark1_y;
yy=curY+ch*yRange/baseSize+0.5;

ch=myread();
if((ch)&8)mark2_x=-1;
chxx=ch=(ch&7)*mark2_x;
xx=curX+(chx+ch)*xRange/baseSize+0.5;

ch=myread();
if((ch)&8)mark2_y=-1;
chyy=ch=(ch&7)*mark2_y;
yy=curY+(chy+ch)*yRange/baseSize+0.5;

ch=myread();
if((ch)&8)mark3_x=-1;
ch=(ch&7)*mark3_x;
xx=curX+(chx+chxx+ch)*xRange/baseSize+0.5;

ch=myread();
if((ch)&8)mark3_y=-1;
ch=(ch&7)*mark3_y;
yy=curY+(chy+chyy+ch)*yRange/baseSize+0.5;
b3_4(xx,yy,COLOR);
curX=xx;curY=yy;
moveto(curX,curY);
break;

case 14:
mark1_x=1;
mark1_y=1;
mark2_x=1;
mark2_y=1;
mark3_x=1;
mark3_y=1;
xx=curX;yy=curY;
ch=myread(); //1
cha=myread(); //2
ch=(ch<<2)+(cha>>2);
if(ch&0x20)mark1_x=-1;
chx=ch=(ch&0x1f)*mark1_x;
xx=curX+ch*xRange/baseSize+0.5;

ch=myread(); //3
ch=((cha&0x03)<<4)+ch;
if(ch&0x20)mark1_y=-1;
chy=ch=(ch&0x1f)*mark1_y;
yy=curY+ch*yRange/baseSize+0.5;

ch=myread(); //1
cha=myread(); //2
ch=(ch<<2)+(cha>>2);
if(ch&0x20)mark2_x=-1;
chxx=ch=(ch&0x1f)*mark2_x;
xx=curX+(chx+ch)*xRange/baseSize+0.5;

ch=myread(); //3
ch=((cha&0x03)<<4)+ch;
if(ch&0x20)mark2_y=-1;
chyy=ch=(ch&0x1f)*mark2_y;
yy=curY+(chy+ch)*yRange/baseSize+0.5;

ch=myread(); //1
cha=myread(); //2
ch=(ch<<2)+(cha>>2);
if(ch&0x20)mark3_x=-1;
ch=(ch&0x1f)*mark3_x;
xx=curX+(chx+chxx+ch)*xRange/baseSize+0.5;

ch=myread(); //3
ch=((cha&0x03)<<4)+ch;
if(ch&0x20)mark3_y=-1;
ch=(ch&0x1f)*mark3_y;
yy=curY+(chy+chyy+ch)*yRange/baseSize+0.5;
b3_4(xx,yy,COLOR);
curX=xx;curY=yy;
moveto(curX,curY);
break;

case 15: //仅读取两个字节,不作处理
readbyte();
readbyte();
break;

}
}

if((readcount<hz.length))lineto(bx,by); //将最后一个笔画的最后一个点与起始点相连,将笔画封闭
getch();
X0+=xRange*168/baseSize+0.5; //此处为168较合适,但未找到原因
if(getmaxx()-X0<xRange*168/baseSize){
X0=0;
Y0+=yRange*168/baseSize+0.5;
}
if(getmaxy()-Y0<yRange*168/baseSize){
Y0=0;
X0=0;
getch();
cleardevice();
}
}
setcolor(oldcolor);
fp=0;
fclose(fpe);
fclose(fpfh);
fclose(fphz);
return;
}



unsigned char myread(void) //每调用一次,读出一个字节的四位数,先读低四位,后读高四位
{
unsigned char a;
if(!next){ //next等于0时读取低四位,为1时读取高四位
a=hzdata&0x0f;
next=1;
}
else{
a=(hzdata&0xf0)>>4;
readcount++;
next=0;
}
return a;
}

int readbyte(void)
{
int kk=0;
unsigned char a,b;
a=myread()<<4;
b=myread();
kk=(int)(b+a);
return kk;
}

void b3_4(int *x,int *y,unsigned long col) //三次B样条曲线,n可以指定常数
{ int n,*bx,*by,sign=1,j=0,k,i;
double a,b,c,d,dt,xx,f0_3,f_0,f_1,f_2;
n=xx=sqrt(((double)(x-x))*((double)(x-x))+
((double)(y-y))*((double)(y-y)))+
sqrt(((double)(x-x))*((double)(x-x))+
((double)(y-y))*((double)(y-y)))+
sqrt(((double)(x-x))*((double)(x-x))+
((double)(y-y))*((double)(y-y)));

if(xx>n) n++;
n*=2;
if(n==0) n=20;
do {
bx=(int *)malloc(n*sizeof(int));
by=(int *)malloc(n*sizeof(int));
if((!bx)||(!by)) {
/*printf("Memory Alloction Error!");*/
return;
}
dt=(double)1/(double)n;
a=((-1)*x+3*x-3*x+x);
b=3*(x-2*x+x);
c=3*(x-x);
d=x;
f0_3=6*a*dt*dt*dt;
f_2=f0_3+2*b*dt*dt;
f_1=f0_3/6+b*dt*dt+c*dt;
f_0=d;
bx=f_0+0.5;
for(i=0;i<n;i++) {
f_0+=f_1;
bx=f_0+0.5;
f_1+=f_2;
f_2+=f0_3;
}
a=((-1)*y+3*y-3*y+y);
b=3*(y-2*y+y);
c=3*(y-y);
d=y;
f0_3=6*a*dt*dt*dt;
f_2=f0_3+2*b*dt*dt;
f_1=f0_3/6+b*dt*dt+c*dt;
f_0=d;
bx=f_0+0.5;
for(i=0;i<n;i++) {
f_0+=f_1;
by=f_0+0.5;
f_1+=f_2;
f_2+=f0_3;
}
sign=1;j=0;k=n/100+1;
for(i=1;i<n;i++) {
if((abs(bx-bx)>1)||(abs(by-by)>1)) j++;
if(j>k) {
free(bx); free(by);
if(n>3) n=n+n/3;
else n=6;
sign=0;
} break;
}
} while(sign==0);
for(i=1;i<n;i++)
if((bx!=bx)||(by!=by)) putpixel(bx,by,col);
free(bx); free(by);
}

void b3_3(int *x,int *y,unsigned long col) //二次B样条曲线,n可以指定常数
{ int n,*bx,*by,sign=1,j=0,k,i;
double a,b,c,d,dt,xx,f0_3,f_0,f_1,f_2;
n=xx=sqrt(((double)(x-x))*((double)(x-x))+
((double)(y-y))*((double)(y-y)))+
sqrt(((double)(x-x))*((double)(x-x))+
((double)(y-y))*((double)(y-y)));

if(xx>n) n++;
n*=4;
if(n==0) n=20;
do {
bx=(int *)malloc(n*sizeof(int));
by=(int *)malloc(n*sizeof(int));
if((!bx)||(!by)) {
/*printf("Memory Alloction Error!");*/
return;
}
dt=(double)1/(double)n;
b=x-2*x+x;
c=2*(x-x);
d=x;
f_2=2*b*dt*dt;
f_1=b*dt*dt+c*dt;
f_0=d;
bx=f_0+0.5;
for(i=0;i<n;i++) {
f_0+=f_1;
bx=f_0+0.5;
f_1+=f_2;
}
b=y-2*y+y;
c=2*(y-y);
d=y;
f_2=2*b*dt*dt;
f_1=b*dt*dt+c*dt;
f_0=d;
by=f_0+0.5;
for(i=0;i<n;i++) {
f_0+=f_1;
by=f_0+0.5;
f_1+=f_2;
}
sign=1;j=0;k=n/100+1;
for(i=1;i<n;i++) {
if((abs(bx-bx)>1)||(abs(by-by)>1)) j++;
if(j>k) {
free(bx); free(by);
if(n>3) n=n+n/3;
else n=6;
sign=0;
} break;
}
} while(sign==0);
for(i=1;i<n;i++)
if((bx!=bx)||(by!=by))
{
putpixel(bx,by,col);

}
free(bx); free(by);
}


   此帖被 +6 点积分     点击查看详情   
评分人:【 DOSroot 分数: +6  时间:2009-4-17 04:07


2009-2-5 22:14
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
lidawei
新手上路





积分 6
发帖 3
注册 2008-2-14
状态 离线
『第 2 楼』:  感谢lhsong的无私奉献 使用 LLM 解释/回答一下

  近日心血来潮,看起了UCDOS的rdfnt.com,虽然DOS的知识已荒废多年,当年的资料也因束之高阁而基本上无法查阅(好象当年手头也没UCDOS的什么资料,现在想找UCDOS系统调用规范之类的东西,google几天都找不到),还是凭兴趣看了好几日,主要看了点阵字库,PS只看了控制码转为坐标部分。虽未看完,但还是再次感叹汇编程序的精致,30来K的程序,其中还有10多K是工作存储区、4-5K是各字库参数定义,指令部分估计也就10多K,如此一小段程序即可完成包括点阵、矢量、PS字库的检索、匹配、解码、变换等操作,真是令人佩服。
  偶见楼主的文章,想谈谈一点自己的看法。
  文章开头部分有

 若字库为5.0版,应去掉下面一段代码
 if(j==1){ //若为汉字,调整地址偏移值
  hz.offset-=0x10000000;
 }

的说明,按我的理解,汉字数据的偏移不应是减去0x10000000,此偏移应该实际只有24bit即3字节,第4字节定义的不是偏移,而是此汉字数据的附加格式。从int 7eh进入rdfnt的获得汉字点阵功能后不远处的一个过程有如下的操作:
 mov   ax,es: 刚才读入的6字节 PS或矢量数据的偏移低字
 mov   dx,es: PS或矢量数据的偏移高字
 mov   cx,es: 长度
 jcxz   ...
 or     zk_type,dh
 mov   dh,0     清0数据指针的最高字节,剩下3字节
...
 call   read_hz    移动文件指针,dx,ax=偏移,读文件,读cx字节于ds:di中
可见其4字节的最高字节不是用于寻址的,而是定义信息。rdfnt除了可读点阵字库、解码PS字库外,尚可解码矢量字库,对于不同的PS、矢量字库,有可能某些字库该字节不是0x10(未各字库逐个汉字检查过,无法证实),如果都减去此一固定值,有可能会出错。
  有一篇文章叫“UCDOS的曲线轮廓字库的分析”,里面也说到ucdos6中偏移应减去0x10000000的事,不知楼主这里的减去0x10000000是否源自该处?


2009-2-18 12:49
查看资料  发短消息  网志   编辑帖子  回复  引用回复
lhsong
初级用户





积分 47
发帖 12
注册 2008-9-5
状态 离线
『第 3 楼』:   使用 LLM 解释/回答一下

谢谢楼上的指点,

“0x10000000”值确实是来自“UCDOS的曲线轮廓字库的分析”一文,不过,我察看了5.0字库和6.0字库,确实是在6.0曲线字库的第四个字节增加了定义,但不知其实际用途。

还希望高手能给予指点。


2009-2-21 21:16
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
oookkk2008
新手上路





积分 5
发帖 2
注册 2009-4-16
状态 离线
『第 4 楼』:   使用 LLM 解释/回答一下

好,学习了,谢谢


2009-4-17 01:53
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
chenyucheng
初级用户

我是新人



积分 152
发帖 70
注册 2023-7-21
来自 浙江省台州市
状态 离线
『第 5 楼』:   使用 LLM 解释/回答一下

 unsigned char *hzstring="然字Mm骤啊H骤g9酆8G字,汉,然。!!戆";//戆您原回骤然燃";//"共有汉字个骤";原骤戆啊汉字

这是什么啊




新手上路!
现在的我来研究研究,我小时没用过的操作系统--DOS。古老的DOS资源比较稀缺,现在新开发的DOS软件也很少,还需要大家的努力,让DOS玩出新花样.
2023-8-1 10:16
查看资料  发送邮件  发短消息  网志  OICQ (744766348)  编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: