game folder "just" compiles (not link)

This commit is contained in:
Ondřej Novák 2025-01-25 13:08:41 +01:00
parent 13d3908273
commit 1b0f7fe0c2
135 changed files with 2161 additions and 2336 deletions

120
libs/addtext.c Normal file
View file

@ -0,0 +1,120 @@
#include <stdlib.h>
#include <stdio.h>
#include "memman.c"
#include "strlite.c"
TSTR_LIST ls_origin=NULL;
TSTR_LIST ls_new=NULL;
static void load_error_msg(int err,char *filename)
{
switch (err)
{
case -1: puts ("Source or target file not found");break;
case -2: puts ("Unexcepted EOF");break;
case -3: puts ("Internal error in strlite.c");break;
default: printf("Error in string table at line %d.\n",err);
}
printf("File:%s\n",filename);
exit(1);
}
void load_lists(char *filename1,char *filename2)
{
int err;
err=load_string_list(&ls_new,filename1);
if (err) load_error_msg(err,filename1);
err=load_string_list(&ls_origin,filename2);
if (err) load_error_msg(err,filename2);
}
char *create_backup(char *filename)
{
char *c,*d;
c=getmem(strlen(filename)+5);strcpy(c,filename);
d=strrchr(c,'.');if (d==NULL) d=strchr(c,0);
strcpy(d,".bak");
remove(c);
rename(filename,c);
return c;
}
void spoj_stringtable()
{
int i;
int cnt=str_count(ls_new);
for(i=0;i<cnt;i++) if (ls_new[i]!=NULL && ls_origin[i]==NULL)
str_replace(&ls_origin,i,ls_new[i]);
}
static void save_num(FILE *fo,int num)
{
char *c=ls_origin[num];
if (c==NULL) return;
fprintf(fo,"%d ",num);
while (*c) if (*c=='\n') (putc('|',fo),c++);else putc(*c++,fo);
putc('\n',fo);
}
void save_stringtable(char *filename,char *backup_name)
{
FILE *fo,*fb;
int cnt=str_count(ls_origin);
int num,rd;
int oldnum=-1,i;
fb=fopen(backup_name,"rt");
if (fb==NULL)
{
puts("Cannot open backup file for reading.");
exit(1);
}
fo=fopen(filename,"wt");
if (fo==NULL)
{
puts("Cannot open target file for writting.");
exit(1);
}
num=0;
rd=fscanf(fb,"%d",&num);
while (num!=-1)
{
if (rd!=1)
do
{
rd=getc(fb);putc(rd,fo);
}
while(rd!='\n');
else
{
for(i=oldnum+1;i<=num;i++) save_num(fo,i);
while((rd=getc(fb))!=EOF && rd!='\n');
}
oldnum=num;
rd=fscanf(fb,"%d",&num);
}
for(i=oldnum+1;i<cnt;i++) save_num(fo,i);
fprintf(fo,"%d",-1);
fclose(fo);
fclose(fb);
}
void main(int argc,char **argv)
{
char *back;
if (argc!=3)
{
puts("Usage: ADDTEXT source target");
exit(1);
}
load_lists(argv[1],argv[2]);
back=create_backup(argv[2]);
spoj_stringtable();
save_stringtable(argv[2],back);
puts("New texts added...");
}

132
libs/advinst.c Normal file
View file

@ -0,0 +1,132 @@
#include <stdio.h>
#include <io.h>
#include <direct.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <dos.h>
char copy_path[500];
char *adv_name;
char _change_disk(unsigned znak)
{
unsigned total;
znak-='@';
_dos_setdrive(znak,&total);
_dos_getdrive(&total);
return total==znak;
}
char disk_finder()
{
static struct find_t ft;
int err;
if (!access("SKELDAL.EXE",F_OK) && !access("ADV",F_OK)) return 1;
err=_dos_findfirst("*.*",_A_SUBDIR,&ft);
while (!err)
{
if (ft.attrib & _A_SUBDIR && strcmp(ft.name,".") && strcmp(ft.name,".."))
{
chdir(ft.name);
if (disk_finder()) return 1;
chdir("..");
}
err=_dos_findnext(&ft);
}
return 0;
}
char find_path(char *path)
{
char *oldpath;
unsigned pismeno='C';
cputs("Hledam...\r");
oldpath=getcwd(NULL,PATH_MAX);
for(pismeno='C';pismeno<='Z';pismeno++)
{
_change_disk(pismeno);
chdir("..");
if (disk_finder()==1)
{
getcwd(path,PATH_MAX);
chdir(oldpath);_change_disk(oldpath[0]);
free(oldpath);
return 1;
}
}
chdir(oldpath);_change_disk(oldpath[0]);
free(oldpath);
return 1;
}
void main(int argc,char **argv)
{
char temp[550];
char rep;
if (argc<2)
{
puts("Nespravne parametry!\n"
"\n"
"Pouziti ADVINST [jmeno]\n"
"\n"
"jmeno = Nazev dobrodruzstvi bez pripony");
return;
}
adv_name=argv[1];
sprintf(temp,"%s.adv",adv_name);
if (access(adv_name,F_OK) && access(temp,F_OK))
{
printf("Nemohu najit zadne dobrodruzstvi s timto jmenem (%s)!\n",adv_name);
return;
}
do
{
printf("Vypiste celou cestu, kde lezi hra (napr: c:\\hry\\skeldal)\n"
"Pokud vlozte otaznik (?), instalator se pokusi hru na disku vyhledat\n"
"Pokud stisknete pouze <ENTER>, instalator se ukonci\n"
">");
gets(copy_path);
if (copy_path[0]=='?')
{
find_path(copy_path);
printf("\nInstalator nasel hru na ceste: %s\n\n",copy_path);
}
if (copy_path[0]==0) return;
sprintf(temp,"%s\\skeldal.exe",copy_path);
rep=access(temp,F_OK);
if (rep) puts("Vami vlozena cesta neni spravna!\n");
else
{
sprintf(temp,"%s\\adv\\%s",copy_path,adv_name);
if (access(temp,F_OK))if (mkdir(temp)!=0) printf("Nedokazal jsem vytvorit adresar %s\n\n\n",temp),rep=1;
}
}
while(rep);
sprintf(temp,"copy %s.adv %s > nul",adv_name,copy_path);
puts(temp);
system(temp);
sprintf(temp,"copy %s\\*.* %s\\adv\\%s > nul",adv_name,copy_path,adv_name);
puts(temp);
system(temp);
sprintf(temp,"%s.bat",adv_name);
if (access(temp,F_OK)==0)
{
sprintf(temp,"%s.bat %s",adv_name,copy_path);
puts(temp);
system(temp);
}
chdir(copy_path);
puts("Instalace uspesna!");
printf("Nove dobrodruzstvi spustis prikazem SKELDAL %s.adv\n",adv_name);
puts("Chces si nyni nove dobrodruzstvi vyzkouset? ANO/NE (cokoliv/N)");
if (toupper(getche())=='N') return;
sprintf(temp,"SKELDAL %s.adv",adv_name);
system(temp);
}

1332
libs/basicobj.c Normal file

File diff suppressed because it is too large Load diff

38
libs/basicobj.h Normal file
View file

@ -0,0 +1,38 @@
#define MEMTEXT "Pamˆt: "
#define E_STATUS_LINE 60
extern word *msg_box_font;
extern word *msg_icn_font;
int msg_box(char *title, char icone, char *text, ... );
void highlight(CTL3D *c,word color);
CTL3D *def_border(int btype,int color);
void xor_rectangle(int x,int y,int xs,int ys);
// status lines
void status_line(EVENT_MSG *msg,T_EVENT_ROOT **user_data);
void *status_mem_info(EVENT_MSG *msg);
void *mouse_xy(EVENT_MSG *msg);
void *show_time(EVENT_MSG *msg);
// objects
//void sample(OBJREC *o);
void button(OBJREC *o);
void win_label(OBJREC *o);
void check_box(OBJREC *o);
void radio_butts(OBJREC *o);
void toggle_button(OBJREC *o);
void input_line(OBJREC *o);
void label(OBJREC *o);
void mid_label(OBJREC *o);
void scroll_bar_v(OBJREC *o);
void scroll_button(OBJREC *o);
void scroll_support();
void scroll_bar_h(OBJREC *o);
void button2(OBJREC *o);
void resizer(OBJREC *o);

261
libs/bgraph.c Normal file
View file

@ -0,0 +1,261 @@
#include "types.h"
//#include <vesa.h>
#include <dpmi.h>
#include <i86.h>
#include <mem.h>
#include <stdio.h>
#include <malloc.h>
#include <graph.h>
#include "bgraph.h"
word *lbuffer;
word *screen;
word curcolor,charcolors[7] = {0x0000,0x03E0,0x0380,0x0300,0x0280,0x0000,0x0000};
longint linelen;
word *curfont,*writepos,writeposx;
byte fontdsize=0;
byte *palmem,*xlatmem;
void (*showview)(word,word,word,word);
char line480=0;
long screen_buffer_size=512000;
void *mscursor,*mssavebuffer=NULL;
integer mscuroldx=0,mscuroldy=0;
integer msshowx=0,msshowy=0;
long pictlen; // Tato promenna je pouze pouzita v BGRAPH1.ASM
void line32(word x1,word y1, word x2, word y2)
{
line_32(x1,y1,(x2-x1),(y2-y1));
}
void position(word x,word y)
{
writeposx=x;
writepos=getadr32(x,y);
}
void outtext(char *text)
{
byte pos;
if (fontdsize)
while (*text)
{
char2_32(writepos,curfont,*text);
pos=(charsize(curfont,*text) & 0xff)<<1;
writepos+=pos;
writeposx+=pos;text++;
}
else
while (*text)
{
char_32(writepos,curfont,*text);
pos=charsize(curfont,*text) & 0xff;
writepos+=pos;
writeposx+=pos;text++;
}
}
int initmode32()
{
MODEinfo data;
getmodeinfo(&data,0x11e-line480*0xe);
if (!(data.modeattr & MA_SUPP)) return -1;
if (!(data.modeattr & MA_LINEARFBUF)) return -2;
setvesamode(0x411e-line480*0xe,-1);
lbuffer=(word *)physicalalloc((long)data.linearbuffer,screen_buffer_size);
screen=lbuffer;
linelen=640*2;
showview=showview32;
screen=(void *)malloc(screen_buffer_size);
return 0;
}
int initmode256(void *paletefile)
{
MODEinfo data;
getmodeinfo(&data,0x100+line480);
if (!(data.modeattr & MA_SUPP)) return -1;
if (!(data.modeattr & MA_LINEARFBUF)) return -2;
setvesamode(0x4100+line480,-1);
lbuffer=(word *)physicalalloc((long)data.linearbuffer,screen_buffer_size>>1);
screen=lbuffer;
linelen=640*2;
palmem=(char *)paletefile;
xlatmem=palmem+768;
setpal((void *)palmem);
showview=showview256;
screen=(void *)malloc(screen_buffer_size);
return 0;
}
int initmode_lo(void *paletefile)
{
_setvideomode(_MRES256COLOR);
palmem=(char *)paletefile;
xlatmem=palmem+768;
setpal((void *)palmem);
linelen=640*2;
lbuffer=(void *)0xa0000;
showview=showview_lo;
screen=(void *)malloc(512000);
return 0;
}
void closemode()
{
free(screen);
_setvideomode(0x3);
}
void showview32(word x,word y,word xs,word ys)
{
register longint a;
if (x>640 || y>400) return;
if (xs==0) xs=640;
if (ys==0) ys=400;
if (x+xs>640) xs=640-x;
if (y+ys>400) ys=400-y;
if (xs>500 && ys>320)
{
redraw32(screen,lbuffer,NULL);
return;
}
a=(x<<1)+linelen*y;
redrawbox32(xs,ys,(void *)((char *)screen+a),(void *)((char *)lbuffer+a));
}
void showview256(word x,word y,word xs,word ys)
{
register longint a;
if (xs==0) xs=640;
if (ys==0) ys=400;
x&=0xfffe;y&=0xfffe;xs+=2;ys+=2;
if (x>640 || y>400) return;
if (x+xs>640) xs=640-x;
if (y+ys>400) ys=400-y;
if (xs>500 && ys>320)
{
redraw256(screen,lbuffer,xlatmem);
return;
}
a=(x<<1)+linelen*y;
redrawbox256(xs,ys,(void *)((char *)screen+a),(void *)((char *)lbuffer+(a>>1)),xlatmem);
}
void showview_lo(word x,word y,word xs,word ys)
{
register longint a,b;
if (xs==0) xs=640;
if (ys==0) ys=400;
x&=0xfffe;y&=0xfffe;xs+=2;ys+=2;
if (ys==0) ys=400;
if (x+xs>640) xs=640-x;
if (y+ys>400) ys=400-y;
if (xs>500 && ys>320)
{
redraw_lo(screen,lbuffer,xlatmem);
return;
}
a=(x<<1)+linelen*y;
b=(x>>1)+320*(y>>1);
redrawbox_lo(xs,ys,(void *)((char *)screen+a),(void *)((char *)lbuffer+b),xlatmem);
}
void show_ms_cursor(char copy,integer x, integer y)
{
integer xs,ys;
xs=*(integer *)mscursor;
ys=*((integer *)mscursor+1);
get_picture(x,y,xs,ys,mssavebuffer);
put_picture(x,y,mscursor);
if (copy)
{
mscuroldx=x;
mscuroldy=y;
}
}
void hide_ms_cursor()
{
put_picture(mscuroldx,mscuroldy,mssavebuffer);
}
void *register_ms_cursor(void *cursor)
{
integer xs,ys;
mscursor=cursor;
xs=*(integer *)mscursor;
ys=*((integer *)mscursor+1);
if (mssavebuffer!=NULL) free(mssavebuffer);
mssavebuffer=malloc(xs*ys*2+10);//5 bajtu pro strejcka prihodu
return mssavebuffer;
}
void move_ms_cursor(integer newx,integer newy)
{
integer xs,ys;
if (newx<0) newx=0;
if (newy<0) newy=0;
if (newx>639) newx=639;
if (newy>399) newy=399;
xs=*(integer *)mscursor;
ys=*((integer *)mscursor+1);
put_picture(mscuroldx,mscuroldy,mssavebuffer);
show_ms_cursor(0,newx,newy);
showview(msshowx,msshowy,xs,ys);
mscuroldx=newx;mscuroldy=newy;
msshowx=newx;msshowy=newy;
showview(msshowx,msshowy,xs,ys);
}
int text_height(char *text)
{
char max=0,cur;
while (*text)
if ((cur=charsize(curfont,*text++)>>8)>max) max=cur;
return max<<fontdsize;
}
int text_width(char *text)
{
int suma=0;
while (*text)
suma+=charsize(curfont,*text++) & 0xff;
return suma<<fontdsize;
}
void set_aligned_position(int x,int y,char alignx,char aligny,char *text)
{
switch (alignx)
{
case 1:x-=text_width(text)>>1;break;
case 2:x-=text_width(text);break;
}
switch (aligny)
{
case 1:y-=text_height(text)>>1;break;
case 2:y-=text_height(text);break;
}
position(x,y);
}

156
libs/bgraph.h Normal file
View file

@ -0,0 +1,156 @@
#include "types.h"
#define line line32
#define hor_line hor_line32
#define ver_line ver_line32
#define bar bar32
#define point point32
word *GetScreenAdr();
long GetScreenSizeBytes();
word *GetBuffer2nd();
void RedirectScreen(word *newaddr);
void RestoreScreen();
void RedirectScreenBufferSecond();
extern word curcolor,charcolors[7];
extern long scr_linelen;
extern long scr_linelen2;
extern long dx_linelen;
extern word *curfont,*writepos,writeposx;
extern byte fontdsize;
extern byte *palmem,*xlatmem;
extern void (*showview)(word,word,word,word);
extern char line480;
extern long screen_buffer_size;
extern char banking;
extern char __skip_change_line_test;
extern char no_restore_mode;
static __inline word *getadr32(longint x,longint y)
{
return GetScreenAdr()+scr_linelen2*y+x;
}
static __inline void point32(longint x,longint y, word color)
{
*getadr32(x,y)=color;
}
void bar32(int x1,int y1, int x2, int y2);
//#pragma aux bar32 parm [eAX] [eBX] [eCX] [eDX] modify [ESI EDI];
void hor_line32(int x1,int y1,int x2);
//#pragma aux hor_line32 parm [eSi] [eAX] [eCX] modify [eDI eDX];
void ver_line32(int x1,int y1,int y2);
//#pragma aux ver_line32 parm [eSi] [eAX] [eCX] modify [eDX];
void hor_line_xor(int x1,int y1,int x2);
//#pragma aux hor_line_xor parm [eSi] [eAX] [eCX] modify [eDI eDX];
void ver_line_xor(int x1,int y1,int y2);
//#pragma aux ver_line_xor parm [eSi] [eAX] [eCX] modify [eDX];
void line_32(int x,int y,int xs,int ys);
//#pragma aux line_32 parm [esi] [eax] [ecx] [ebx] modify [edx edi]
void char_32(word *posit,word *font,char znak);
//#pragma aux char_32 parm [edi] [esi] [eax] modify [eax ebx ecx edx]
void char2_32(word *posit,word *font,char znak);
//#pragma aux char2_32 parm [edi] [esi] [eax] modify [eax ebx ecx edx]
word charsize(word *font,char znak);
//#pragma aux charsize parm [esi] [eax]
void put_picture(word x,word y,void *p);
//#pragma aux put_picture parm [esi] [eax] [edi] modify [ebx ecx edx]
void get_picture(word x,word y,word xs,word ys,void *p);
//#pragma aux get_picture parm [esi] [eax] [ebx] [ecx] [edi] modify [edx]
void setpal(void *paleta);
//#pragma aux setpal parm [esi] modify [eax edx]
void redraw_lo(void *screen,void *lbuffer,byte *xlat);
//#pragma aux redraw_lo parm [esi][edi][ebx] modify[eax ecx edx]
void redraw256(void *screen,void *lbuffer,byte *xlat);
//#pragma aux redraw256 parm [esi][edi][ebx] modify [eax ecx edx]
void redraw256b(void *screen,void *lbuffer,byte *xlat);
//#pragma aux redraw256b parm [esi][edi][ebx] modify [eax ecx edx]
void redraw32(void *screen,void *lbuffer,byte *xlat);
//#pragma aux redraw32 parm [esi][edi][ebx] modify [ecx]
void redraw32b(void *screen,void *lbuffer,byte *xlat);
//#pragma aux redraw32b parm [esi][edi][ebx] modify [ecx eax]
void redraw64(void *screen,void *lbuffer,byte *xlat);
//#pragma aux redraw64 parm [esi][edi][ebx] modify [ecx eax]
void redraw64b(void *screen,void *lbuffer,byte *xlat);
//#pragma aux redraw64b parm [esi][edi][ebx] modify [ecx eax]
void redraw32bb(void *screen,void *lbuffer,byte *xlat);
//#pragma aux redraw32bb parm [esi][edi][ebx] modify [ecx eax]
void redrawbox_lo(word xs,word ys,void *screen,void *lbuffer,byte *xlat);
//#pragma aux redrawbox_lo parm [ecx][edx][esi][edi][ebx] modify [eax edx]
void redrawbox256(word xs,word ys,void *screen,void *lbuffer,byte *xlat);
//#pragma aux redrawbox256 parm [edx][ecx][esi][edi][ebx] modify [eax edx]
void redrawbox256b(word xs,word ys,void *screen,void *lbuffer,byte *xlat);
//#pragma aux redrawbox256b parm [edx][ecx][esi][edi][ebx] modify [eax edx]
void redrawbox32(word xs,word ys,void *screen,void *lbuffer);
//#pragma aux redrawbox32 parm [ebx][edx][esi][edi] modify [ecx eax]
void redrawbox32b(word xs,word ys,void *screen,void *lbuffer);
//#pragma aux redrawbox32b parm [ebx][edx][esi][edi] modify [ecx eax]
void redrawbox64(word xs,word ys,void *screen,void *lbuffer,byte *xlat);
//#pragma aux redrawbox64 parm [ecx][edx][esi][edi][ebx] modify [eax]
void redrawbox64b(word xs,word ys,void *screen,void *lbuffer,byte *xlat);
//#pragma aux redrawbox64b parm [ecx][edx][esi][edi][ebx]modify [eax]
void redrawbox32bb(word xs,word ys,void *screen,void *lbuffer);
//#pragma aux redrawbox32bb parm [ebx][edx][esi][edi] modify [ecx]
void redraw16(void *screen,void *lbuffer,byte *xlat);
void redrawbox16(word xs,word ys,void *screen,void *lbuffer,byte *xlat);
//#pragma aux redrawbox16 parm [edx][ecx][esi][edi][ebx] modify [eax edx]
//#pragma aux redraw16 parm [esi][edi][ebx] modify [ecx]
void showview32(word x,word y,word xs,word ys);
void showview256(word x,word y,word xs,word ys);
void showview_lo(word x,word y,word xs,word ys);
void outtext(char *text);
int initmode_dx(char inwindow, char zoom, char monitor, int refresh);
int initmode32();
int initmode32b();
int initmode256(void *paletefile);
int initmode256b(void *paletefile);
int initmode_lo(void *paletefile);
int initmode16(void *paletefile);
int initmode64(void *paletefile);
int initmode64b(void *paletefile);
void *create_hixlat();
void closemode();
void line32(word x1,word y1, word x2, word y2);
void position(word x,word y);
void outtext(char *text);
void show_ms_cursor(integer x,integer y);
void *register_ms_cursor(void *cursor);
void move_ms_cursor(integer newx,integer newy,char nodraw);
void hide_ms_cursor();
int text_height(char *text);
int text_width(char *text);
void set_aligned_position(int x,int y,char alignx, char aligny,char *text);
void wait_retrace();
void pal_optimize();
void rectangle(int x1,int y1,int x2,int y2,int color);
word *mapvesaadr1(word *a);
void *create_special_palette();
void *create_special_palette2();
void *create_blw_palette16();
void rel_position_x(word x);
int init_empty_mode();
void put_8bit_clipped(void *src,void *trg,int startline,int velx,int vely);
//#pragma aux put_8bit_clipped parm [ESI][EDI][EAX][EBX][EDX] modify [ECX];
void put_textured_bar_(void *src,void *trg,int xsiz,int ysiz,int xofs,int yofs);
//#pragma aux put_textured_bar_ parm [EBX][EDI][EDX][ECX][ESI][EAX];
void put_textured_bar(void *src,int x,int y,int xs,int ys,int xofs,int yofs);
void trans_bar(int x,int y,int xs,int ys,int barva);
//#pragma aux trans_bar parm [EDI][ESI][EDX][ECX][EBX] modify [EAX];
void trans_bar25(int x,int y,int xs,int ys);
//#pragma aux trans_bar25 parm [EDI][ESI][EDX][ECX] modify [EAX EBX];
void trans_line_x(int x,int y,int xs,int barva);
//#pragma aux trans_line_x parm [EDI][ESI][ECX][EDX] modify [EAX];
void trans_line_y(int x,int y,int ys,int barva);
//#pragma aux trans_line_y parm [EDI][ESI][ECX][EDX] modify [EAX];
void draw_placed_texture(short *txtr,int celx,int cely,int posx,int posy,int posz,char turn);
void put_image(word *image,word *target,int start_line,int sizex,int sizey);
//#pragma aux put_image parm [ESI][EDI][EAX][EBX][EDX] modify [ECX]
void put_picture2picture(word *source,word *target,int xp,int yp);
//#pragma aux put_picture2picture parm [ESI][EDI][EAX][EDX] modify [ECX]
#define swap_int(a,b) do {int c=a;a=b;b=c;} while (0);

658
libs/bgraph1.asm Normal file
View file

@ -0,0 +1,658 @@
.model small
.386
DGROUP group _DATA
extrn _linelen:dword
extrn _screen:dword
extrn _curcolor:word
extrn _charcolors:word[7]
extrn _pictlen:dword
extrn _screen_buffer_size:dword
SEGA000 equ 0a0000h
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
public getadr32_
getadr32_:
getadr_:mul _linelen ;EAX - y; ESI - X;
shl esi,1
add eax,esi
add eax,_screen
ret
public point32_ ;EAX - Y; ESI - X; ECX - COLOR
point32_: call getadr_
mov [eax],cx
ret
public bar32_ ;AX - X1, BX - Y1, CX - X2, DX - Y2
bar32_: cmp cx,ax ;x1<x2
jnc bar2
xchg ax,cx ;neni-li, prohod je
bar2: cmp dx,bx ;y1<y2
jnc bar3
xchg bx,dx ;neni-li, prohod je
bar3: push es ;uchovej es
push edx ;uchovej edx
mov dx,ds ;prekopiruj ds do es
mov es,dx
and eax,0ffffh ;vymuluj hornich 16-bitu z eax
mov esi,eax
mov ax,bx
call getadr_ ;Zjisti adresu (ESI - X, EAX - Y)
xchg esi,eax ;ESI adresa, v eax je X
shr eax,1
pop edx ;obnov edx
sub dx,bx ;dx=y2-y1+1;
inc dx
sub cx,ax ;cx=x2-x1+1
inc cx
and ecx,0ffffh ;vynuluj hodnich 16-biy ecx
mov ebx,ecx ;uchovej ecx v ebx
mov ax,_curcolor ;nacti aktualni barvu
shl eax,16 ;hodnotu odroluj do horni poloviny
mov ax,_curcolor ;nacti aktualni barvu jeste jednou
bar1: mov edi,esi ;edi je pozice leveho sloupce obdelniku
shr ecx,1 ;ecx/2 po 32-bitech
rep stosd ;zapis linky
rcl ecx,1 ;pokud byla sirka licha je v ecx cislo 1
rep stosw ;zapis pripadneho jednoho bodu
mov ecx,ebx ;obnov ecx
add esi,_linelen ;jdi na dalsi radek
dec dx ;sniz dx - citac
jnz Bar1 ;dokud neni vsechno
pop es ;obnoc es
ret
public hor_line32_
Hor_line32_: ;EAX - Y ESI - X1 ECX - X2
call getadr_ ;eax obsahuje adresu bodu
shr esi,1
push es ;uchovej es
cmp ecx,esi ;x2>x1
jnc horlin1
xchg ecx,esi ;jestli ne tak je prohod
horlin1:sub ecx,esi ;xs=x2-x1+1
inc ecx ;
mov si,ds ;ds -> es
mov es,si
mov edi,eax ;esi je adresa
mov ax,_curcolor ;nacti barvu
shl eax,16
mov ax,_curcolor
shr ecx,1
rep stosd ;nakresli caru
rcl ecx,1
rep stosw ;popripade jeste jeden bod
pop es ;obnov es
ret
public ver_line32_
ver_line32_: ;EAX - Y1 ESI - X ECX - Y2
cmp ecx,eax ;y2>y1
jnc verlin1
xchg ecx,eax ;jestli ne tak je prohod
verlin1:sub ecx,eax
inc ecx
call getadr_ ;eax obsahuje adresu bodu
mov esi,eax
mov ax,_curcolor ;nacti barvu
verlin2:mov [esi],ax ;kresli caru po bodech
add esi,_linelen
dec ecx
jnz verlin2
ret
public line_32_
line_32_: ;eax - Y, esi - X, ecx - xs, ebx - ys (xs,ys muze byt zaporne)
or ecx,ecx
jns line1 ;kdyz je ecx (xs) zaporny je nutne otocit smer a presunout se na druhy konec linky
add esi,ecx
add eax,ebx
neg ebx
neg ecx
line1: push es ;uchovej es
or ecx,ecx ;kdyz je ecx=0 pak je to specialni pripad
inc ecx
jz lnext
call getadr_ ;zjisti adresu prvnihi bodu
mov edi,eax ;vloz ji do di
mov ax,ds ;ds -> es
mov es,ax
mov ax,_curcolor ;nacti aktualni barvu
or ebx,ebx ;kontrola zda je ebx>=0
js lineup ;neni pak bude se kreslit nahoru
xor esi,esi ;vynuluj esi - pocitadlo mezikroku
mov edx,ecx ;delku cary na ose x do porovnavaciho registru
inc ebx
lined3: add esi,ebx ;do mezikroku pricti ys
cmp esi,edx ;kdyz to prekrocilo poronavaci registr
jc lined1 ;zacnes kreslit dolu, jinak v pravo
lined2: mov [edi],ax;zapis bod
add edi,_linelen ;a posun dolu
sub esi,edx ;odect od mezikroku hodnotu v porovnavacim registru
cmp esi,edx ;je stale preteceni?
jnc lined2 ;pokud ano opakuj zapsani bodu
add edi,2 ;dalsi xs
dec ecx ;sniz citac Xs
jnz lined3 ;pokracuj pro dalsi Xs
jmp linee ;pokud to byl posledni, pak konec
lined1: stosw ;zapis bod a posun v pravo
dec ecx ;pokracuj pro dalsi ys
jnz lined3 ;dokud neni konec
jmp linee ;pak jdi na lineEnd
lineup: neg ebx ;neguj ebx
xor esi,esi ;vynuluj esi - pocitadlo mezikroku
mov edx,ecx ;delku cary na ose x do porovnavaciho registru
inc ebx
lineu3: add esi,ebx ;do mezikroku pricti ys
cmp esi,edx ;kdyz to prekrocilo poronavaci registr
jc lineu1 ;zacnes kreslit nahoru, jinak v pravo
lineu2: mov [edi],ax;zapis bod
sub edi,_linelen ;a posun nahoru
sub esi,edx ;odect od mezikroku hodnotu v porovnavacim registru
cmp esi,edx ;je stale preteceni?
jnc lineu2 ;pokud ano opakuj zapsani bodu
add edi,2 ;dalsi xs
dec ecx ;sniz citac Xs
jnz lineu3 ;pokracuj pro dalsi Xs
jmp linee ;pokud to byl posledni, pak konec
lineu1: stosw ;zapis bod a posun v pravo
dec ecx ;pokracuj pro dalsi ys
jnz lineu3 ;dokud neni konec
jmp linee
lnext: mov ecx,ebx
add ecx,eax
call ver_line32_
linee: pop es
ret
public char_32_
char_32_: ;edi - pozice na obrazovce
;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chrend
add esi,eax
lodsw
xor dl,dl ;dl - je citac transparetnich pozic
mov cx,ax ;cl - XRES, ch - YRES
chr6: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci
mov dh,ch ;dh - bude citac radku
chr5: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt
jnz chr1 ;jinak je dalsi bod jenom transparetni
lodsb ;cti barvu
or al,al ;pokud je 0 pak je transparetni
jz chr2 ;preskoc kresleni
cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech
jnc chr3 ;(viz FONTEDIT.DOC). Pak se podle toho zarid
and eax,0ffh;v eax jen dolnich 8 bitu
dec al
mov ax,_charcolors[EAX*2] ;vyjmi barvu
cmp ax,0ffffh;0xffff je barva ktera se nekresli;
jz chr4 ;
mov [ebx],ax;zobraz ji na obrazovce
jmp chr4 ;a skoc na konec smycky
chr3: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator.
jz chrend ;V tom pripade KONEC
sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic
mov dl,al ;uloz je do citace
chr1: dec dl ;pro kazdou pozici to dl odecti dokud neni 0
chr2:
chr4: add ebx,_linelen;dalsi radka
dec dh ;odecti citac radek
jnz chr5 ;dokud neni nula
add edi,2 ;dalsi sloupec
dec cl ;odecti citac sloupcu
jnz chr6 ;dokud neni nula
chrend: ret ;konec
public char2_32_
char2_32_: ;edi - pozice na obrazovce
;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chr2end
add esi,eax
lodsw
xor dl,dl ;dl - je citac transparetnich pozic
mov cx,ax ;cl - XRES, ch - YRES
chr26: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci
mov dh,ch ;dh - bude citac radku
chr25: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt
jnz chr21 ;jinak je dalsi bod jenom transparetni
lodsb ;cti barvu
or al,al ;pokud je 0 pak je transparetni
jz chr22 ;preskoc kresleni
cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech
jnc chr23 ;(viz FONTEDIT.DOC). Pak se podle toho zarid
and eax,0ffh;v eax jen dolnich 8 bitu
dec al
mov ax,_charcolors[EAX*2] ;vyjmi barvu
push ebx
mov [ebx],ax;zobraz ji na obrazovce
mov [ebx+2],ax;zobraz ji na obrazovce
add ebx,_linelen
mov [ebx],ax;zobraz ji na obrazovce
mov [ebx+2],ax;zobraz ji na obrazovce
pop ebx
jmp chr24 ;a skoc na konec smycky
chr23: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator.
jz chr2end ;V tom pripade KONEC
sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic
mov dl,al ;uloz je do citace
chr21: dec dl ;pro kazdou pozici to dl odecti dokud neni 0
chr22:
chr24: add ebx,_linelen;dalsi radka
add ebx,_linelen
dec dh ;odecti citac radek
jnz chr25 ;dokud neni nula
add edi,4 ;dalsi sloupec
dec cl ;odecti citac sloupcu
jnz chr26 ;dokud neni nula
chr2end: ret ;konec
public charsize_
charsize_: ;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chsend
add esi,eax
lodsw
chsend: and eax,0ffffh
ret
public put_picture_
put_picture_: ;esi - X
;eax - Y
;edi - obrazek
mov ecx,esi ;uchovej x v ecx
mov ebx,eax ;uchovej y v ebx
call getadr_ ;zjisti adresu bodu
mov esi,eax ;vloz ji do esi
xchg esi,edi ;prohod esi a edi aby obsahovali zpravne informace
xor eax,eax ;vynuluj pripadne bajty v horni polovine eax
lodsw ;nacti xs
mov _pictlen,eax
mov edx,eax ;z kopiruj jeste do pracovniho dx
add edx,ecx ;pricti k nemu souradnici
cmp edx,640 ;je-li vetsi nez max velikost obrazovky x
jc ppok1 ;
mov eax,640 ;pak za eax dosad plnou velikost
sub eax,ecx ;odecti souradnici
ppok1: mov ecx,eax ;vloz do ecx
lodsw ;totez pro y
mov edx,eax
add edx,ebx
cmp edx,400
jc ppok2
mov eax,400
sub eax,ebx
ppok2: mov edx,eax
lodsw
mov ebx,edi
cmp al,15
jnz pp_next
jmp pp15bit
pp_next:cmp al,8
jnz pp_nxt2
jmp pp8bit
pp_nxt2:ret
pp15bit:mov eax,ecx
pp15bi1:shr ecx,1
rep movsd
rcl ecx,1
rep movsw
mov ecx,_pictlen
sub ecx,eax
shl ecx,1
add esi,ecx
mov ecx,eax
add ebx,_linelen
mov edi,ebx
dec edx
jnz pp15bi1
ret
pp8bit: push ebp
mov ebp,ecx
mov ebx,esi
add esi,512
pp8bit1:xor eax,eax
lodsb
or al,al
jz pp8bit2
mov eax,[ebx+eax*2]
stosw
pp8bit4:dec ecx
jnz pp8bit1
mov ecx,ebp
sub edi,ecx
sub edi,ecx
add edi,_linelen
sub esi,ebp
add esi,_pictlen
dec edx
jnz pp8bit1
pop ebp
ret
pp8bit2:add edi,2
jmp pp8bit4
public setPal_
setPal_:mov edx,3c6h
mov al,255
out dx,al
xor ah,ah
setpal1:mov edx,3c8h
mov al,ah
out dx,al
mov edx,3c9h
lodsb
out dx,al
lodsb
out dx,al
lodsb
out dx,al
inc ah
jne setPal1
ret
public Redraw_lo_
Redraw_lo_: ;esi 512Kb obrazovka
;edi lbuffer
;ebx xlattable
test ebx,1
jz rdrwlo3
inc ebx
rdrwlo3:push ebp
mov ebp,200 shl 16
xor eax,eax
xor ecx,ecx
xor edx,edx
rdrwlo2:mov bp,160
rdrwlo1:mov ecx,[esi]
mov edx,[esi+1280]
and ecx,7bdf7bdfh
and edx,7bdf7bdfh
add ecx,edx
shr ecx,1
shrd ecx,edx,16
and edx,7bdfh
and ecx,7bdfh
add edx,ecx
shr edx,1
mov al,[ebx+edx*2]
xor ebx,1
add esi,4
mov ecx,[esi]
mov edx,[esi+1280]
and ecx,7bdf7bdfh
and edx,7bdf7bdfh
add ecx,edx
shr ecx,1
shrd ecx,edx,16
and edx,7bdfh
and ecx,7bdfh
add edx,ecx
shr edx,1
mov ah,[ebx+edx*2]
stosw
xor ebx,1
add esi,4
dec bp
jnz rdrwlo1
xor ebx,1
add esi,1280
sub ebp,65536
jnz rdrwlo2
pop ebp
ret
public Redraw256_
Redraw256_: ;esi - source
;edi - target
;ebx - xlat
test ebx,1
jz rdrwlo7
inc ebx
rdrwlo7:xor eax,eax
rdrwlo4:mov ecx,400*65536
rdrwlo6:mov cx,320
rdrwlo5:mov edx,[esi]
add esi,4
mov ax,dx
mov al,[ebx+eax*2]
shr edx,16
xor ebx,1
mov ah,[ebx+edx*2]
stosw
xor ebx,1
dec cx
jnz rdrwlo5
xor ebx,1
sub ecx,65536
jnz rdrwlo6
ret
public redraw32_
redraw32_: ;esi source
;edi target
;ebx notused (xlat)
mov ecx,128000
rep movsd
ret
public redrawbox_lo_
redrawbox_lo_: ;esi source
;edi target
;ebx xlat
;ecx xs
;edx,ys
shr ecx,1
shr edx,1
dec edx
test ebx,1
jz rboxlo3
inc ebx
rboxlo3:push ebp
mov ebp,edx
shl ebp,16
mov bp,cx
xor eax,eax
xor ecx,ecx
xor edx,edx
rboxlo2:push ebp
push esi
push edi
rboxlo1:mov ecx,[esi]
mov edx,[esi+1280]
and ecx,7bdf7bdfh
and edx,7bdf7bdfh
add ecx,edx
shr ecx,1
shrd ecx,edx,16
and edx,7bdfh
and ecx,7bdfh
add edx,ecx
shr edx,1
mov al,[ebx+edx*2]
stosb
xor ebx,1
add esi,4
dec bp
jnz rboxlo1
pop edi
pop esi
pop ebp
xor ebx,1
add esi,_linelen
add esi,_linelen
add edi,320
sub ebp,65536
jnc rboxlo2
pop ebp
ret
public Redrawbox256_
Redrawbox256_: ;esi - source
;edi - target
;ebx - xlat
;ecx - ys
;edx - xs
shl ecx,16
shr edx,1
mov cx,dx
test ebx,1
jz rboxlo7
inc ebx
rboxlo7:xor eax,eax
rboxlo6:push ecx
push esi
push edi
rboxlo5:mov edx,[esi]
add esi,4
mov ax,dx
mov al,[ebx+eax*2]
shr edx,16
xor ebx,1
mov ah,[ebx+edx*2]
stosw
xor ebx,1
dec cx
jnz rboxlo5
pop edi
pop esi
pop ecx
add esi,_linelen
add edi,640
xor ebx,1
sub ecx,65536
test ecx,0ffff0000h
jnz rboxlo6
ret
public redrawbox32_
redrawbox32_: ;esi source
;edi target
;ebx xs
;edx ys
shr ebx,1
rbox32: mov ecx,ebx
rep movsd
mov ecx,ebx
shl ecx,2
sub esi,ecx
sub edi,ecx
add esi,_linelen
add edi,_linelen
dec edx
jnz rbox32
ret
public get_picture_
get_picture_: ;esi - X
;eax - Y
;ebx - xs
;ecx - ys
;edi - obrazek
mov [edi],ebx ;zapis velikost obrazku
mov [edi+2],ecx
mov ecx,esi ;uchovej x v ecx
mov ebx,eax ;uchovej y v ebx
call getadr_ ;zjisti adresu bodu
mov esi,eax ;vloz ji do esi
xor eax,eax ;vynuluj pripadne bajty v horni polovine eax
mov ax,[edi];vem velikost x
add edi,2
mov _pictlen,eax
mov edx,eax ;z kopiruj jeste do pracovniho dx
add edx,ecx ;pricti k nemu souradnici
cmp edx,640 ;je-li vetsi nez max velikost obrazovky x
jc gpok1 ;
mov eax,640 ;pak za eax dosad plnou velikost
sub eax,ecx ;odecti souradnici
gpok1: mov ecx,eax ;vloz do ecx
mov ax,[edi];vem velikost y
add edi,2
mov edx,eax
add edx,ebx
cmp edx,400
jc gpok2
mov eax,400
sub eax,ebx
gpok2: mov edx,eax
mov ax,15 ;nastav typ 15
stosw ;zapis
mov ebx,esi ;uloz esi jeste do ebx
gp15bit:mov eax,ecx ;uloz ecx jeste do eax
gp15bi1:shr ecx,1 ;pocet dvojic bodu
rep movsd ;presun do pameti
rcl ecx,1 ;pokud zbyl jeste jeden
rep movsw ;tak ted
mov ecx,_pictlen
sub ecx,eax
shl ecx,1
add edi,ecx ;jdi na dalsi radku v obrazku
mov ecx,eax ;obnov counter
add ebx,_linelen ;jdi na dalsi radku na obrazovce
mov esi,ebx ;obnov esi
dec edx ;dokud neni konec
jnz gp15bi1
ret
public hor_line_xor_
Hor_line_xor_: ;EAX - Y ESI - X1 ECX - X2
call getadr_ ;eax obsahuje adresu bodu
shr esi,1
cmp ecx,esi ;x2>x1
jnc xhorlin1
xchg ecx,esi ;jestli ne tak je prohod
xhorlin1:sub ecx,esi ;xs=x2-x1+1
inc ecx ;
mov edi,eax ;esi je adresa
mov ax,_curcolor ;nacti barvu
xhorlin2:xor [edi],ax
add edi,2
dec ecx
jnz xhorlin2
ret
public ver_line_xor_
ver_line_xor_: ;EAX - Y1 ESI - X ECX - Y2
cmp ecx,eax ;y2>y1
jnc xverlin1
xchg ecx,eax ;jestli ne tak je prohod
xverlin1:sub ecx,eax
inc ecx
call getadr_ ;eax obsahuje adresu bodu
mov esi,eax
mov ax,_curcolor ;nacti barvu
xverlin2:xor [esi],ax ;kresli caru po bodech
add esi,_linelen
dec ecx
jnz xverlin2
ret
_TEXT ends
END

800
libs/bgraph2.c Normal file
View file

@ -0,0 +1,800 @@
#include <skeldal_win.h>
#include "types.h"
//#include <vesa.h>
//#include <dpmi.h>
//#include <i86.h>
#include <mem.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
//#include <graph.h>
#include <conio.h>
#include "bgraph.h"
#include "memman.h"
word *screen;
word curcolor,charcolors[7] = {0x0000,RGB555(0,31,0),RGB555(0,28,0),RGB555(0,24,0),RGB555(0,20,0),0x0000,0x0000};
long scr_linelen;
long scr_linelen2;
long dx_linelen;
word *curfont,*writepos,writeposx;
byte fontdsize=0;
byte *palmem=NULL,*xlatmem=NULL;
void (*showview)(word,word,word,word);
char line480=0;
long screen_buffer_size=0;
char banking=0;
char screenstate=0;
char __skip_change_line_test=0;
char no_restore_mode=0;
void *mscursor,*mssavebuffer=NULL;
integer mscuroldx=0,mscuroldy=0;
integer mscuroldxs=1,mscuroldys=1;
char write_window=0;
long pictlen; // Tato promenna je pouze pouzita v BGRAPH1.ASM
void text_mode();
void wait_retrace();
void line32(word x1,word y1, word x2, word y2)
{
line_32(x1,y1,(x2-x1),(y2-y1));
}
void position(word x,word y)
{
writeposx=x;
writepos=getadr32(x,y);
}
void rel_position_x(word x)
{
writeposx+=x;
writepos+=x;
}
void outtext(char *text)
{
byte pos;
if (fontdsize)
while (*text)
{
char2_32(writepos,curfont,*text);
pos=(charsize(curfont,*text) & 0xff)<<1;
writepos+=pos;
writeposx+=pos;text++;
}
else
while (*text)
{
char_32(writepos,curfont,*text);
pos=charsize(curfont,*text) & 0xff;
writepos+=pos;
writeposx+=pos;text++;
}
}
/*MODEinfo vesadata[3];
SVGAinfo svgadata[3];
int lastbank=0;
int granuality=0;
int gran_mask=0;
word gr_page_end=0;
int gr_end_screen=0;
word *mapvesaadr(word *a);
#pragma aux mapvesaadr parm [edi] value [edi]
void write_vesa_info(int mode)
{
char c[20];
getsvgainfo(&svgadata);
printf("VIDEO mem %5dKb\n"
"Oem: %s\n\n",
svgadata[0].memory*64,
svgadata[0].oemstr);
getmodeinfo(&vesadata,mode);
if (vesadata[0].modeattr & MA_SUPP)
{
if (vesadata[0].modeattr & MA_LINEARFBUF) sprintf(c,"%8Xh",(long)vesadata[0].linearbuffer); else strcpy(c,"None");
printf("Mode: %04X \n"
"WinA %02X\n"
"WinB %02X\n"
"Granuality: %5dKB\n"
"WinSize: %5dKB\n"
"Xres: %5d\n"
"Yres: %5d\n"
"Bppix: %5d\n"
"Lbuffer: %s\n\n",
mode,
vesadata[0].winaattr,
vesadata[0].winbattr,
vesadata[0].wingran,
vesadata[0].winsize,
vesadata[0].xres,
vesadata[0].yres,
vesadata[0].bppix,
c);
}
else printf("Mode %04X not currently supported!!!\n\n");
// printf("--- Hit ENTER if values are correct or press CTRL+Break ---\n");
// getche();
delay(300);
}
*/
void showview_dx(word x,word y,word xs,word ys);
//void showview64b(word x,word y,word xs,word ys);
/*void showview32b(word x,word y,word xs,word ys)
{
register longint a,b;
if (x>640 || y>480) return;
if (xs==0) xs=640;
if (ys==0) ys=480;
xs++;ys++;
x&=~3;
xs=(xs & ~3)+4;
if (x+xs>640) xs=640-x;
if (y+ys>480) ys=480-y;
if (xs>550 && ys>400)
{
redraw32bb(screen,NULL,NULL);
return;
}
a=(x<<1)+linelen*y;
b=y*1280+x*2;
redrawbox32bb(xs,ys,(void *)((char *)screen+a),(void *)b);
}
*/
/*
void set_scan_line(int newline);
#pragma aux set_scan_line=\
"mov eax,4f06h"\
"xor ebx,ebx"\
"int 10h"\
parm [ecx] modify [eax ebx];
int get_scan_line();
#pragma aux get_scan_line=\
"mov eax,4f06h"\
"mov bh,01"\
"int 10h"\
modify[eax ebx] value[ecx];
void *create_hixlat()
{
word *s;
word i;
s=NewArr(word,32768);
for (i=0;i<32768;i++) s[i]=((i & ~0x1f)<<1) | (i & 0x1f);
return (byte *)s;
}
int initmode64b(void *paletefile)
{
int i;
getmodeinfo(&vesadata,0x111);
if (!(vesadata[0].modeattr & MA_SUPP)) return -1;
//write_vesa_info(0x110);
if (vesadata[0].winaattr & (WA_SUPP | WA_WRITE)) write_window=0;
else if (vesadata[0].winbattr & (WA_SUPP | WA_WRITE)) write_window=1;
else return -1;
i=vesadata[0].wingran*1024;
granuality=0;lastbank=0;
while (i>>=1) granuality++;
gran_mask=(1<<granuality)-1;
gr_end_screen=0xa0000+gran_mask+1;
gr_page_end=gran_mask+1;
setvesamode(0x111,-1);
lbuffer=(word *)0xa0000;
screen=lbuffer;
linelen=640*2;
showview=showview64b;
screen=(void *)malloc(screen_buffer_size);
banking=1;
screenstate=1;
xlatmem=paletefile;
return 0;
}
int initmode32b()
{
int i;
getmodeinfo(&vesadata,0x110);
if (!(vesadata[0].modeattr & MA_SUPP)) return -1;
//write_vesa_info(0x110);
if (vesadata[0].winaattr & (WA_SUPP | WA_WRITE)) write_window=0;
else if (vesadata[0].winbattr & (WA_SUPP | WA_WRITE)) write_window=1;
else return -1;
i=vesadata[0].wingran*1024;
granuality=0;lastbank=0;
while (i>>=1) granuality++;
gran_mask=(1<<granuality)-1;
gr_end_screen=0xa0000+gran_mask+1;
gr_page_end=gran_mask+1;
setvesamode(0x110,-1);
lbuffer=(word *)0xa0000;
screen=lbuffer;
linelen=640*2;
showview=showview32b;
screen=(void *)malloc(screen_buffer_size);
banking=1;
screenstate=1;
return 0;
}
int initmode32bb()
{
int i;
getmodeinfo(&vesadata,0x110);
if (!(vesadata[0].modeattr & MA_SUPP)) return -1;
//write_vesa_info(0x110);
if (vesadata[0].winaattr & (WA_SUPP | WA_WRITE)) write_window=0;
else if (vesadata[0].winbattr & (WA_SUPP | WA_WRITE)) write_window=1;
else return -1;
i=vesadata[0].wingran*1024;
granuality=0;lastbank=0;
while (i>>=1) granuality++;
setvesamode(0x110,-1);
set_scan_line(1024);
if (get_scan_line()!=1024 && !__skip_change_line_test)
{
text_mode();
return -10;
}
lbuffer=(word *)0xa0000;
screen=lbuffer;
linelen=640*2;
showview=showview32b;
screen=(void *)malloc(screen_buffer_size);
banking=1;
screenstate=1;
return 0;
}
word *mapvesaadr1(word *a)
{
word bank;
bank=(long)a>>16;
if (bank!=lastbank)
{
lastbank=bank;
bank=bank;
{
union REGS regs;
regs.w.ax = 0x4f05;
regs.w.bx = write_window;
regs.w.dx = bank;
int386 (0x10,&regs,&regs); // window A
}
}
return (word *)(((long)a & 0xffff)+0xa0000);
}
void switchvesabank(word bank)
#pragma aux switchvesabank parm [eax]
{
union REGS regs;
regs.w.ax = 0x4f05;
regs.w.bx = 0;
regs.w.dx = bank;
int386 (0x10,&regs,&regs); // window A
}
*/
int initmode_dx(char inwindow, char zoom, char monitor, int refresh)
{
if (!DXInit64(inwindow,zoom,monitor,refresh)) return -1;
showview=showview_dx;
screenstate=1;
scr_linelen2=scr_linelen/2;
return 0;
}
/*
int initmode256(void *paletefile)
{
MODEinfo data;
getmodeinfo(&data,0x100+line480);
if (!(data.modeattr & MA_SUPP)) return initmode256b(paletefile);
if (!(data.modeattr & MA_LINEARFBUF)) return initmode256b(paletefile);
//write_vesa_info(0x101);
setvesamode(0x4101,-1);
if (lbuffer==NULL)lbuffer=(word *)physicalalloc((long)data.linearbuffer,screen_buffer_size>>1);
screen=lbuffer;
linelen=640*2;
palmem=(char *)paletefile;
xlatmem=palmem+768;
setpal((void *)palmem);
showview=showview256;
screen=(void *)malloc(screen_buffer_size);
screenstate=1;
banking=0;
return 0;
}
void showview256b(word x,word y,word xs,word ys)
{
register longint a,b;
if (x>640 || y>480) return;
if (xs==0) xs=640;
if (ys==0) ys=480;
xs++;ys++;
x&=~3;
xs=(xs & ~3)+4;
y&=~1;
ys=(ys & ~1)+2;
if (x+xs>640) xs=640-x;
if (y+ys>480) ys=480-y;
if (xs>550 && ys>400)
{
redraw256b(screen,0,xlatmem);
return;
}
a=(x<<1)+linelen*y;
b=y*640+x;
redrawbox256b(xs,ys,(void *)((char *)screen+a),(void *)b,xlatmem);
}
int initmode256b(void *paletefile)
{
int i;
getmodeinfo(&vesadata,0x100);
if (!(vesadata[0].modeattr & MA_SUPP)) return -1;
//write_vesa_info(0x101);
i=vesadata[0].wingran*1024;
if (vesadata[0].winaattr & (WA_SUPP | WA_WRITE)) write_window=0;
else if (vesadata[0].winbattr & (WA_SUPP | WA_WRITE)) write_window=1;
else return -1;
granuality=0;lastbank=0;
while (i>>=1) granuality++;
gran_mask=(1<<granuality)-1;
gr_end_screen=0xa0000+gran_mask+1;
gr_page_end=gran_mask+1;
setvesamode(0x101,-1);
lbuffer=(word *)0xa0000;
screen=lbuffer;
palmem=(char *)paletefile;
xlatmem=palmem+768;
setpal((void *)palmem);
linelen=640*2;
showview=showview256b;
screen=(void *)malloc(screen_buffer_size);
banking=1;
screenstate=1;
return 0;
}
void init_lo();
#pragma aux init_lo modify[eax ebx ecx edx esi edi]
int initmode_lo(void *paletefile)
{
init_lo();
palmem=(char *)paletefile;
xlatmem=palmem+768;
setpal((void *)palmem);
linelen=640*2;
lbuffer=0;
showview=showview_lo;
screen=(void *)malloc(screen_buffer_size);
screenstate=1;
banking=1;
return 0;
}
*/
void closemode()
{
if (screenstate)
{
palmem=NULL;
DXCloseMode();
}
screenstate=0;
}
static void showview_dx(word x,word y,word xs,word ys)
{
// register longint a;
if (x>DxGetResX() || y>DxGetResY()) return;
if (xs==0) xs=DxGetResX();
if (ys==0) ys=DxGetResY();
xs+=2;ys+=2;
if (x+xs>DxGetResX()) xs=DxGetResX()-x;
if (y+ys>DxGetResY()) ys=DxGetResY()-y;
DXCopyRects64(x,y,xs,ys);
}
/*
static void showview64b(word x,word y,word xs,word ys)
{
register longint a;
if (x>640 || y>480) return;
if (xs==0) xs=640;
if (ys==0) ys=480;
xs+=2;ys+=2;
if (x+xs>640) xs=640-x;
if (y+ys>480) ys=480-y;
if (xs>550 && ys>400)
{
redraw64b(screen,NULL,xlatmem);
return;
}
a=(x<<1)+linelen*y;
redrawbox64b(xs,ys,(void *)((char *)screen+a),(void *)((char *)a),xlatmem);
}
void showview256(word x,word y,word xs,word ys)
{
register longint a;
if (xs==0) xs=640;
if (ys==0) ys=480;
x&=0xfffe;y&=0xfffe;xs+=2;ys+=2;
if (x>640 || y>480) return;
if (x+xs>640) xs=640-x;
if (y+ys>480) ys=480-y;
if (xs>550 && ys>400)
{
redraw256(screen,lbuffer,xlatmem);
return;
}
a=(x<<1)+linelen*y;
redrawbox256(xs,ys,(void *)((char *)screen+a),(void *)((char *)lbuffer+(a>>1)),xlatmem);
}
void showview_lo(word x,word y,word xs,word ys)
{
register longint a,b;
if (xs==0) xs=640;
if (ys==0) ys=480;
if (ys==0) ys=480;
x&=0xfffe;y&=0xfffe;xs+=2;ys+=2;
if (x+xs>640) xs=640-x;
if (y+ys>480) ys=480-y;
if (xs>550 && ys>400)
{
redraw_lo(screen,lbuffer,xlatmem);
return;
}
a=(x<<1)+linelen*y;
b=x+640*y;
redrawbox_lo(xs,ys,(void *)((char *)screen+a),(void *)((char *)lbuffer+b),xlatmem);
}
*/
void show_ms_cursor(integer x,integer y)
{
integer xs,ys;
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
if (x<0) x=0;
if (x>mx) mx=639;
if (y<0) y=0;
if (y>my) my=479;
xs=*(integer *)mscursor;
ys=*((integer *)mscursor+1);
get_picture(x,y,xs,ys,mssavebuffer);
put_picture(x,y,mscursor);
mscuroldx=x;
mscuroldy=y;
}
void hide_ms_cursor()
{
put_picture(mscuroldx,mscuroldy,mssavebuffer);
}
void *register_ms_cursor(void *cursor)
{
integer xs,ys;
mscursor=cursor;
xs=*(integer *)mscursor;
ys=*((integer *)mscursor+1);
if (mssavebuffer!=NULL) free(mssavebuffer);
mssavebuffer=malloc(xs*ys*2+10);//5 bajtu pro strejcka prihodu
return mssavebuffer;
}
void move_ms_cursor(integer newx,integer newy,char nodraw)
{
integer xs,ys;
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
static integer msshowx=0,msshowy=0;
xs=*(integer *)mscursor;
ys=*((integer *)mscursor+1);
if (nodraw)
{
showview(msshowx,msshowy,xs,ys);
msshowx=mscuroldx;
msshowy=mscuroldy;
return;
}
if (newx<0) newx=0;
if (newy<0) newy=0;
if (newx>mx) newx=mx;
if (newy>my) newy=my;
put_picture(mscuroldx,mscuroldy,mssavebuffer);
show_ms_cursor(newx,newy);
mscuroldx=newx;mscuroldy=newy;
showview(msshowx,msshowy,mscuroldxs,mscuroldys);
if (mscuroldx!=msshowx || mscuroldy!=msshowy)showview(mscuroldx,mscuroldy,mscuroldxs,mscuroldys);
msshowx=newx;msshowy=newy;
showview(msshowx,msshowy,xs,ys);
mscuroldxs=xs;
mscuroldys=ys;
}
int text_height(char *text)
{
char max=0,cur;
while (*text)
if ((cur=charsize(curfont,*text++)>>8)>max) max=cur;
return max<<fontdsize;
}
int text_width(char *text)
{
int suma=0;
while (*text)
suma+=charsize(curfont,*text++) & 0xff;
return suma<<fontdsize;
}
void set_aligned_position(int x,int y,char alignx,char aligny,char *text)
{
switch (alignx)
{
case 1:x-=text_width(text)>>1;break;
case 2:x-=text_width(text);break;
}
switch (aligny)
{
case 1:y-=text_height(text)>>1;break;
case 2:y-=text_height(text);break;
}
position(x,y);
}
/*void pal_optimize()
{
long *stattable;
word *c;
char *d;
int i;
long maxr,maxg,maxb,max;
int j;
if (palmem==NULL) return;
stattable=(long *)getmem(32768*sizeof(long));
memset(stattable,0,32768*sizeof(long));
c=screen;
for(i=0;i<screen_buffer_size;i++,c++)
stattable[*c & 0x7fff]++;
for(j=0;j<256;j++)
{
max=0;
for (i=0;i<32768;i++)
if (stattable[i]>max)
{
*((word *)xlatmem+j)=i;
max=stattable[i];
}
stattable[*((word *)xlatmem+j)]=-1;
}
d=palmem;
c=(word *)xlatmem;
for(i=0;i<256;i++)
{
j=*c++;
*d++=((j>>9)& 0x3e);
*d++=((j>>4)& 0x3e);
*d++=(j & 0x1f)<<1;
}
setpal((void *)palmem);
memset(xlatmem,0,65536);
for(j=0;j<32768;j++)
{
int r1,g1,b1;
int r2,g2,b2,dif;
char *c;
maxr=maxg=maxb=999999999;
r1=(j>>9)& 0x3e;g1=(j>>4)& 0x3e;b1=(j & 0x1f)<<1;
c=palmem;
for(i=0;i<256;i++)
{
r2=abs(r1-*c++);
g2=abs(g1-*c++);
b2=abs(b1-*c++);
dif=r2+b2+g2;
if (dif<=maxb)
{
if (dif<maxb) xlatmem[j*2]=i;
else xlatmem[j*2]=xlatmem[j*2+1];
xlatmem[j*2+1]=i;
maxb=dif;
}
}
}
showview(0,0,0,0);
free(stattable);
}
*/
void rectangle(int x1,int y1,int x2,int y2,int color)
{
curcolor=color;
hor_line(x1,y1,x2);
hor_line(x1,y2,x2);
ver_line(x1,y1,y2);
ver_line(x2,y1,y2);
}
void *create_special_palette()
{
char *c;
int i,j,k;
void *z;
z=c=getmem(3*256+2*32768);
for(i=0;i<6;i++)
for(j=0;j<7;j++)
for(k=0;k<6;k++)
{*c++=12*i;*c++=10*j;*c++=12*k;}
c=z;
c+=768;
for(i=0;i<32;i++)
for(j=0;j<32;j++)
for(k=0;k<32;k++)
{
*c++=((i+3)/6)*42+((j+3)/5)*6+((k+3)/6);
*c++=(i*2/12)*42+(j/5)*6+(k*2/12);
}
return z;
}
void *create_special_palette2()
{
char *c;
int i,j,k;
void *z;
z=c=getmem(3*256+2*32768);
for(i=0;i<64;i++)
{
*c++=0;*c++=i;*c++=0;
}
for(j=0;j<24;j++)
for(k=0;k<8;k++)
{*c++=j*64/24;*c++=0;*c++=k*8;}
c=z;
c+=768;
for(i=0;i<32;i++)
for(j=0;j<32;j++)
for(k=0;k<32;k++)
{
*c++=64+(i*24/32)*8+k/4;
*c++=j*2;
}
return z;
}
void *create_blw_palette16()
{
char *c;
int i,j,k;
void *z;
char pal_colors[]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
char carnat[]={0,1,3,2,4,5,7,6,12,13,15,14,8,9,11,10};
z=c=getmem(3*256+2*32768);
for(i=0;i<16;i++)
{
j=pal_colors[carnat[i]]*3;k=i*4+3;
c[j]=k;c[j+1]=k;c[j+2]=k;
}
c+=768;
for(i=0;i<32;i++)
for(j=0;j<32;j++)
for(k=0;k<32;k++)
{
int u=(i*3+j*5+k*2)/10;
c[0]=carnat[u/2];
c[1]=carnat[(u+1)/2];
c+=2;
}
return z;
}
/*
void showview16(word x,word y,word xs,word ys)
{
int x1,x2;
if (x>640 || y>480) return;
if (xs==0) xs=640;
if (ys==0) ys=480;
if (x+xs>640) xs=640-x;
if (y+ys>480) ys=480-y;
if (xs>550 && ys>400)
{
redraw16(screen,lbuffer,xlatmem);
return;
}
x1=x & ~0x7;
x2=(x+xs+7) & ~0x7;
redrawbox16((x2-x1)/8,ys,screen+x1+640*y,(char *)lbuffer+x1/8+80*y,xlatmem);
}
void init16colors();
#pragma aux init16colors modify [eax]=\
"mov eax,12h"\
"int 10h"\
int initmode16(void *palette)
{
palette;
init16colors();
lbuffer=(word *)0xa0000;
screen=lbuffer;
linelen=640*2;
showview=showview16;
screen=(void *)malloc(screen_buffer_size);
palmem=(char *)palette;
xlatmem=palmem+768;
setpal((void *)palmem);
banking=0;
screenstate=1;
return 0;
}
void empty_show_view(int x,int y,int xs,int ys)
{
x,y,xs,ys;
}
int init_empty_mode()
{
screen=(void *)malloc(screen_buffer_size);
showview=empty_show_view;
banking=1;
lbuffer=NULL;
screenstate=1;
return 0;
}
*/

1132
libs/bgraph2a.asm Normal file

File diff suppressed because it is too large Load diff

758
libs/bgraph2a.c Normal file
View file

@ -0,0 +1,758 @@
#include <skeldal_win.h>
#include "types.h"
#include "bgraph.h"
#include <debug.h>
void bar32(int x1,int y1, int x2, int y2)
{
word *begline;
int i,j;
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
if (x1>x2) swap_int(x1,x2);
if (y1>y2) swap_int(y1,y2);
if (x1<0) x1=0;
if (y1<0) y1=0;
if (x2>mx) x2=mx;
if (y2>my) y2=my;
for (i=y1,begline=GetScreenAdr()+scr_linelen2*i;i<=y2;i++,begline+=scr_linelen2)
{
for (j=x1;j<=x2;j++) begline[j]=curcolor;
}
}
void hor_line32(int x1,int y1,int x2)
{
word *begline;
int i;
unsigned long curcolor2=curcolor | (curcolor<<16);
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
if (y1<0 || y1>my) return;
if (x1>x2) swap_int(x1,x2);
if (x1<0) x1=0;
if (x2>mx) x2=mx;
begline=GetScreenAdr()+scr_linelen2*y1;
for (i=x1;i<x2;i+=2) *(unsigned long *)(begline+i)=curcolor2;
if (i==x2) begline[i]=curcolor;
}
void ver_line32(int x1,int y1,int y2)
{
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
word *begline;
int i;
if (y1>y2) swap_int(y1,y2);
if (x1<0 || x1>mx) return;
if (y1<0) y1=0;
if (y2>my) y2=my;
begline=GetScreenAdr()+scr_linelen2*y1+x1;
for (i=y1;i<=y2;i++,begline+=scr_linelen2) *begline=curcolor;
}
void hor_line_xor(int x1,int y1,int x2)
{
word *begline;
int i;
unsigned long curcolor2=curcolor | (curcolor<<16);
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
if (y1<0 || y1>my) return;
if (x1>x2) swap_int(x1,x2);
if (x1<0) x1=0;
if (x2>mx) x2=mx;
begline=GetScreenAdr()+scr_linelen2*y1;
for (i=x1;i<x2;i+=2) *(unsigned long *)(begline+i)^=curcolor2;
if (i==x2) begline[i]^=curcolor;
}
void ver_line_xor(int x1,int y1,int y2)
{
word *begline;
int i;
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
if (y1>y2) swap_int(y1,y2);
if (x1<0 || x1>mx) return;
if (y1<0) y1=0;
if (y2>my) y2=my;
begline=GetScreenAdr()+scr_linelen2*y1+x1;
for (i=y1;i<=y2;i++,begline+=scr_linelen2) *begline^=curcolor;
}
void line_32(int x,int y,int xs,int ys)
{
int xp,yp,ly;
if (xs==0) {ver_line32(x,y,y+ys);return;}
if (ys==0) {hor_line32(x,y,x+xs);return;}
if (xs<0)
{
x=x+xs;
y=y+ys;
ys=-ys;
xs=-xs;
}
ly=y;
for (xp=0;xp<=xs;xp++)
{
yp=(xp*ys+(xs>>1))/xs+y;
{
ver_line32(xp+x,ly,yp);
ly=yp+(ys>0)-(ys<0);
}
}
}
void char_32(word *posit,word *font,char znak)
//#pragma aux char_32 parm [edi] [esi] [eax] modify [eax ebx ecx edx]
{
word *edi = posit;
unsigned char *esi = font;
int al = znak;
unsigned char dl,cl,ch,dh;
word *ebx;
word ax = esi[al*2]+256*esi[al*2+1];
if (ax == 0) goto chrend;
esi += ax;
dl = 0;
cl = *esi++;
ch = *esi++;
chr6:
ebx = edi;
dh = ch;
chr5:
if (dl != 0) goto chr1;
al = *esi++;
if (al == 0) goto chr2;
if (al >= 8) goto chr3;
ax = charcolors[(al-1)];
if (ax == 0xffff) goto chr4;
*ebx = ax;
goto chr4;
chr3:if (al == 255) goto chrend;
dl = al - 6;
chr1: dl--;
chr2:
chr4: ebx+=scr_linelen2;
dh--;
if (dh!=0) goto chr5;
edi++;
cl--;
if (cl!=0) goto chr6;
chrend:;
/*
__asm
{
mov edi,posit;
mov esi,font;
mov al,znak
;edi - pozice na obrazovce
;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chrend
add esi,eax
lodsw
xor dl,dl ;dl - je citac transparetnich pozic
mov cx,ax ;cl - XRES, ch - YRES
chr6: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci
mov dh,ch ;dh - bude citac radku
chr5: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt
jnz chr1 ;jinak je dalsi bod jenom transparetni
lodsb ;cti barvu
or al,al ;pokud je 0 pak je transparetni
jz chr2 ;preskoc kresleni
cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech
jnc chr3 ;(viz FONTEDIT.DOC). Pak se podle toho zarid
and eax,0ffh;v eax jen dolnich 8 bitu
dec al
mov ax,short ptr charcolors[EAX*2] ;vyjmi barvu
cmp ax,0xffff ;0xffff je barva ktera se nekresli;
jz chr4 ;
mov [ebx],ax;zobraz ji na obrazovce
jmp chr4 ;a skoc na konec smycky
chr3: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator.
jz chrend ;V tom pripade KONEC
sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic
mov dl,al ;uloz je do citace
chr1: dec dl ;pro kazdou pozici to dl odecti dokud neni 0
chr2:
chr4: add ebx,scr_linelen;dalsi radka
dec dh ;odecti citac radek
jnz chr5 ;dokud neni nula
add edi,2 ;dalsi sloupec
dec cl ;odecti citac sloupcu
jnz chr6 ;dokud neni nula
chrend: ;konec
}
*/
}
void char2_32(word *posit,word *font,char znak)
//#pragma aux char2_32 parm [edi] [esi] [eax] modify [eax ebx ecx edx]
{
//nevim jestli se vola a kdy se vola, takze necham puvodni obsluhu
char_32(posit,font,znak);
/*__asm
{
mov edi,posit
mov esi,font
mov al,znak
;edi - pozice na obrazovce
;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chr2end
add esi,eax
lodsw
xor dl,dl ;dl - je citac transparetnich pozic
mov cx,ax ;cl - XRES, ch - YRES
chr26: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci
mov dh,ch ;dh - bude citac radku
chr25: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt
jnz chr21 ;jinak je dalsi bod jenom transparetni
lodsb ;cti barvu
or al,al ;pokud je 0 pak je transparetni
jz chr22 ;preskoc kresleni
cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech
jnc chr23 ;(viz FONTEDIT.DOC). Pak se podle toho zarid
and eax,0ffh;v eax jen dolnich 8 bitu
dec al
mov ax,charcolors[EAX*2] ;vyjmi barvu
push ebx
mov [ebx],ax;zobraz ji na obrazovce
mov [ebx+2],ax;zobraz ji na obrazovce
add ebx,scr_linelen
mov [ebx],ax;zobraz ji na obrazovce
mov [ebx+2],ax;zobraz ji na obrazovce
pop ebx
jmp chr24 ;a skoc na konec smycky
chr23: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator.
jz chr2end ;V tom pripade KONEC
sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic
mov dl,al ;uloz je do citace
chr21: dec dl ;pro kazdou pozici to dl odecti dokud neni 0
chr22:
chr24: add ebx,scr_linelen;dalsi radka
add ebx,scr_linelen
dec dh ;odecti citac radek
jnz chr25 ;dokud neni nula
add edi,4 ;dalsi sloupec
dec cl ;odecti citac sloupcu
jnz chr26 ;dokud neni nula
chr2end: ;konec
}
*/
}
word charsize(word *font,char znak)
{
unsigned char *esi = font;
int al = znak;
unsigned char cl,ch;
word ax = esi[al*2]+256*esi[al*2+1];
if (ax == 0) return 0;
esi += ax;
cl = *esi++;
ch = *esi++;
ax = (int)cl+256*(int)ch;
return ax;
/*
//#pragma aux charsize parm [esi] [eax]
__asm
{
mov esi,font
mov al,znak
;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chsend
add esi,eax
lodsw
chsend: and eax,0ffffh
}*/
}
void put_picture(word x,word y,void *p)
//#pragma aux put_picture parm [esi] [eax] [edi] modify [ebx ecx edx]
{
word *adr=GetScreenAdr()+scr_linelen2*y+x;
word *data=p;
word xs=data[0];
word ys=data[1];
word mode=data[2];
word xss=xs;
word yss=ys;
if (x+xss>=DxGetResX()) xss=DxGetResX()-x;
if (y+yss>=DxGetResY()) yss=DxGetResY()-y;
data+=3;
if (mode==15)
{
int i;
int j;
for (i=0;i<yss;i++,adr+=scr_linelen2,data+=(xs-xss))
for (j=0;j<xss;j++)
{
adr[j]=((*data & ~0x1f)<<1) | (*data & 0x1f);
data++;
}
}
if (mode==16)
{
int i;
int j;
for (i=0;i<yss;i++,adr+=scr_linelen2,data+=(xs-xss))
for (j=0;j<xss;j++)
{
adr[j]=*data;
data++;
}
}
if (mode==8 || mode==264)
{
word *table=data;
char *cdata=(char *)(data+(mode==264?10*256:256));
int i;
int j;
for (i=0;i<yss;i++,adr+=scr_linelen2,cdata+=(xs-xss))
for (j=0;j<xss;j++)
{
if (*cdata)
adr[j]=table[*cdata];
cdata++;
}
}
else if (mode==512 )
{
word *table=data;
char *cdata=(char *)(data+256);
int i;
int j;
for (i=0;i<yss;i++,adr+=scr_linelen2,cdata+=(xs-xss))
for (j=0;j<xss;j++)
{
if (*cdata)
adr[j]=table[*cdata]+(table[*cdata] & ~0x1F);
cdata++;
}
}
}
void get_picture(word x,word y,word xs,word ys,void *p)
{
word *adr=GetScreenAdr()+scr_linelen2*y+x;
word *data=p;
word xss=xs;
word yss=ys;
if (x+xss>=DxGetResX()) xss=DxGetResX()-x;
if (y+yss>=DxGetResY()) yss=DxGetResY()-y;
data[0]=xss;
data[1]=yss;
data[2]=16;
data+=3;
{
int i;
int j;
for (i=0;i<yss;i++,adr+=scr_linelen2)
for (j=0;j<xss;j++)
{
*data=adr[j];
data++;
}
}
}
void put_image(word *image,word *target,int start_line,int sizex,int sizey)
//#pragma aux put_image parm [ESI][EDI][EAX][EBX][EDX] modify [ECX]
{
word *esi = image;
word *edi = target;
int eax = start_line;
int ebx = sizex;
int edx = sizey;
int ecx = esi[0];
esi = esi + 3 + start_line * ecx;
while (edx) {
memcpy(edi,esi,ecx*2);
esi += ecx;
edi += scr_linelen2;
edx--;
}
/*
__asm
{
mov esi,image
mov edi,target
mov eax,start_line
mov ebx,sizex
mov edx,sizey
;ESI - obrazek
;EDI - obrazovka
;EAX - startline
;EBX - velikostx
;EDX - velikosty
shl eax,1
xor ecx,ecx
mov cx,[esi]
imul eax,ecx
add esi,eax
add esi,6
mov eax,ecx
puti_lp:mov ecx,ebx
shr ecx,1
rep movsd
rcl ecx,1
rep movsw
mov ecx,eax
sub ecx,ebx
add esi,ecx
sub edi,ebx
sub edi,ebx
add edi,scr_linelen
dec edx
jnz puti_lp
}*/
}
void put_8bit_clipped(void *src,void *trg,int startline,int velx,int vely)
//#pragma aux put_8bit_clipped parm [ESI][EDI][EAX][EBX][EDX] modify [ECX];
{
if (src==NULL) return;
{
word *esi = src;
word *edi = trg;
word *paleta = esi+3;
int cx = esi[0];
unsigned char *imgdata = (unsigned char *)(esi + 3 + 256)+ startline * cx;
while (vely) {
int i;
for (i = 0; i < velx; i++)
if (imgdata[i]) edi[i] = paleta[imgdata[i]];
imgdata += cx;
edi += scr_linelen2;
vely--;
}
}
}
/*_asm
{
mov esi,src
mov edi,trg
mov eax,startline
mov ebx,velx
mov edx,vely
;ESI - obrazek
;EDI - obrazovka
;EAX - startline
;EBX - velikostx
;EDX - velikosty
push ebp
mov ebp,ebx
xor ecx,ecx
mov cx,[esi]
imul eax,ecx
lea ebx,[esi+6];
add esi,6+512
add esi,eax
mov eax,ecx
put8_lp:mov ecx,ebp
push eax
put8lp2:xor eax,eax
lodsb
or eax,eax
jz put8_trns
mov eax,[ebx+eax*2]
stosw
put8nxt:dec ecx
jnz put8lp2
pop eax
mov ecx,eax
sub ecx,ebp
add esi,ecx
sub edi,ebp
sub edi,ebp
add edi,scr_linelen
dec edx
jnz put8_lp
pop ebp
jmp ende
put8_trns:
add edi,2
jmp put8nxt
ende:
}*/
void put_textured_bar_(void *src,void *trg,int xsiz,int ysiz,int xofs,int yofs)
//#pragma aux put_textured_bar_ parm [EBX][EDI][EDX][ECX][ESI][EAX];
{
word *imghdr = (word *)src;
word cx = imghdr[0];
word cy = imghdr[1];
word tp = imghdr[2];
word *paleta = imghdr+3;
word *target = (word *)trg;
unsigned char *imgdata = (unsigned char *)(paleta+256);
int y;
xofs = xofs % cx;
if (tp != 8) return;
for (y = 0; y < ysiz; y++) {
int yf = (yofs + y) % cy;
unsigned char *row = imgdata +(yf * cx);
int x;
for (x = 0; x < xsiz; x++) {
unsigned char c = row[(x + xofs) % cx];
if (c) target[x] = paleta[c];
}
target+=scr_linelen2;
}
}
/*
__asm
{
mov ebx,src
mov edi,trg
mov edx,xsiz
mov ecx,ysiz
mov esi,xofs
mov eax,yofs
;zobrazi texturovany obdelnik tvoreny cyklickou texturou
;vstup
; EDI - pozice na obrazovce
; EBX - textura
; ECX - velikosty
; EDX - velikostx
; EAX - yofs
; ESI - xofs
push ebp ;uchovej EBP - bude pouzit jako univerzalni registr
mov ebp,eax ;zacneme o EAX radku v texture niz
shl edx,16 ;nachvili uchovej dx v horni pulce
mul short ptr [ebx] ;zjisti pocatecni adresu v texture
shl eax,16
shrd eax,edx,16 ;EAX=AX*word ptr[ebx]
shr edx,16
xchg esi,eax ;napln esi pocatkem
lea esi,[esi+512] ;vypocti zacatek v texture+xlat
lea ebx,[ebx+6] ;postav ebx na zacatek xlat
add esi,ebx ;pricti zacatek textury
add esi,eax ;pricti k ukazateli ofset v x
ptb_l2: push eax ;uchovej xofset
push edx ;uchovej velikost v x
push esi ;uchovej zacatek radky v texture
shl ebp,16 ;odsun citac offset do horni pulky ebp
add bp,ax ;pricti k bp offset v x
ptb_l1: xor eax,eax ;pred kazdym bodem vynuluj eax
lodsb ;nacti barvu
or al,al
jz ptb_s1
mov ax,[ebx+eax*2];vyhledej barvu v palete
mov [edi],ax ;zapis hicolor barvu
ptb_s1: add edi,2
inc bp ;zvys counter v x
cmp bp,[ebx-6] ;byl dosazen pravy roh textury?
jc ptb_skip1 ;ne pokracuj
mov ax,bp ;nacti eax counterem
sub esi,eax ;odexti to cele od esi - tj spatky doleva
xor bp,bp
ptb_skip1:
dec edx
jnz ptb_l1
shr ebp,16 ;vrat counter pro y
pop esi ;obnov pocatek v texture
mov ax,[ebx-6] ;nalouduj do eax delku x (horni pulka je zarucene prazdna)
add esi,eax ;pricti k esi
inc ebp ;zvys y counter
cmp bp,[ebx-4] ;test zda jsme dosahli dolniho rohu textury
jc ptb_skip2 ;ne pokracuj
mov eax,ebp ;ano nalouduj eax
mul short ptr [ebx-6];vynasob ho delkou v x
shl eax,16
shrd eax,edx,16 ;eax=ax*word ptr [ebx-4]
sub esi,eax ;jsme na zacatku
xor ebp,ebp
ptb_skip2:
pop edx ;obnov zbyvajici registry
pop eax
add edi,scr_linelen;
sub edi,edx
sub edi,edx
dec ecx ;odecti 1 od globalniho citace radek
jnz ptb_l2 ;konec velke smycky
POP EBP
}
}
*/
#define MIXTRANSP(a,b) ((((a) & 0xF7DE)+((b) & 0xF7DE))>>1)
void trans_bar(int x,int y,int xs,int ys,int barva)
{
word *begline;
int x1=x;
int y1=y;
int x2=x+xs-1;
int y2=y+ys-1;
int i,j;
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
if (x1>x2) swap_int(x1,x2);
if (y1>y2) swap_int(y1,y2);
if (x1<0) x1=0;
if (y1<0) y1=0;
if (x2>mx) x2=mx;
if (y2>my) y2=my;
for (i=y1,begline=GetScreenAdr()+scr_linelen2*i;i<=y2;i++,begline+=scr_linelen2)
{
for (j=x1;j<=x2;j++) begline[j]=MIXTRANSP(begline[j],barva);
}
}
void trans_line_x(int x,int y,int xs,int barva)
{
trans_bar(x,y,xs,1,barva);
}
void trans_line_y(int x,int y,int ys,int barva)
{
trans_bar(x,y,1,ys,barva);
}
void trans_bar25(int x,int y,int xs,int ys)
{
word *begline;
int x1=x;
int y1=y;
int x2=x+xs-1;
int y2=y+ys-1;
int i,j;
int mx = DxGetResX() - 1;
int my = DxGetResY() - 1;
if (x1>x2) swap_int(x1,x2);
if (y1>y2) swap_int(y1,y2);
if (x1<0) x1=0;
if (y1<0) y1=0;
if (x2>mx) x2=mx;
if (y2>my) y2=my;
for (i=y1,begline=GetScreenAdr()+scr_linelen2*i;i<=y2;i++,begline+=scr_linelen2)
{
for (j=x1;j<=x2;j++) begline[j]=MIXTRANSP(begline[j],MIXTRANSP(begline[j],0));
}
}
void wait_retrace()
{
}
#define pic_start (2+2+2+512*5+512*5)
void put_picture2picture(word *source,word *target,int xp,int yp)
//#pragma aux put_picture2picture parm [ESI][EDI][EAX][EDX] modify [ECX]
{
word *srchdr = (word *)source;
word *trghdr = (word *)target;
word src_cx = srchdr[0];
word trg_cx = trghdr[0];
word src_cy = srchdr[1];
word trg_cy = trghdr[1];
word y;
unsigned char *srcimagedata = (unsigned char *)source+pic_start;
unsigned char *trgimagedata = (unsigned char *)target+pic_start;
trgimagedata+=trg_cx * yp + xp;
for (y = 0; y < src_cy; y++) {
word x;
for (x = 0; x < src_cx; x++) {
if (srcimagedata[x]) trgimagedata[x] = srcimagedata[x];
}
trgimagedata+=trg_cx;
srcimagedata+=src_cx;
}
}/*
__asm
{
mov esi,source
mov edi,target
mov eax,xp
mov edx,yp
;ESI - obrazek 256c
;EDI - obrazek 256
;EAX - Xpos
;EDX - Ypos
movzx ecx,short ptr [edi] ;vyzvedni sirku obrazku
imul edx,ecx ;nova adresa=edi+(Xpos+sirka*Ypos)
add eax,edx
mov edx,ecx
lea edi,[edi+eax+pic_start] ;edi obsahuje novou adresu
mov ecx,[esi] ;ecx obsahuje Xsize a Ysize obrazku
sub ecx,10000h ;Ysize-1
lea esi,[esi+pic_start] ;nastav esi na zacatek bitmapy
ppp_lp2:push ecx ;uchovej velikosti obrazku v zasobniku
ppp_lp1:lodsb ;nacti bod ze zdroje
or al,al ;zkontroluj zda to neni transparentni barva
jz ppp_trn ;pokud je tak ji prezskoc
mov [edi],al ;zapis barvu
ppp_trn:inc edi ;dalsi bod
dec cx ;odecitej x sirku
jnz ppp_lp1 ;dokud to neni vse
pop ecx ;obnov ecx
movzx eax,cx ;vem jeste jednou sirku
sub eax,edx ;spocitej kolik bajtu je nutne
sub edi,eax ;prezkocit k dosazeni dalsi radky
sub ecx,10000h ;opakuj pro y radku
jnc ppp_lp2
}
}*/

206
libs/bgraph2a.cpp Normal file
View file

@ -0,0 +1,206 @@
#include <skeldal_win.h>
#include "types.h"
#include "bgraph.h"
#include <debug.h>
void bar32(int x1,int y1, int x2, int y2)
{
word *begline;
int i,j;
if (x1>x2) swap_int(x1,x2);
if (y1>y2) swap_int(y1,y2);
if (x1<0) x1=0;
if (y1<0) y1=0;
if (x2>639) x2=639;
if (y2>479) y2=479;
for (i=y1,begline=screen+scr_linelen2*y1;i<=y2;i++,begline+=scr_linelen2)
{
for (j=x1;j<=x2;j++) begline[j]=curcolor;
}
}
void hor_line32(int x1,int y1,int x2)
{
word *begline;
int i;
unsigned long curcolor2=curcolor | (curcolor<<16);
if (y1<0 || y1>479) return;
if (x1>x2) swap_int(x1,x2);
if (x1<0) x1=0;
if (x2>639) x2=639;
begline=screen+scr_linelen2*y1;
for (i=x1;i<x2;i+=2) *(unsigned long *)(begline+i)=curcolor2;
if (i==x2) begline[i]=curcolor;
}
void ver_line32(int x1,int y1,int y2)
{
word *begline;
int i;
if (y1>y2) swap_int(y1,y2);
if (x1<0 || x1>639) return;
if (y1<0) y1=0;
if (y2>479) y2=479;
begline=screen+scr_linelen2*y1+x1;
for (i=y1;i<=y2;i++,begline+=scr_linelen2) *begline=curcolor;
}
void hor_line_xor(int x1,int y1,int x2)
{
word *begline;
int i;
unsigned long curcolor2=curcolor | (curcolor<<16);
if (y1<0 || y1>479) return;
if (x1>x2) swap_int(x1,x2);
if (x1<0) x1=0;
if (x2>639) x2=639;
begline=screen+scr_linelen2*y1;
for (i=x1;i<x2;i+=2) *(unsigned long *)(begline+i)^=curcolor2;
if (i==x2) begline[i]^=curcolor;
}
void ver_line_xor(int x1,int y1,int y2)
{
word *begline;
int i;
if (y1>y2) swap_int(y1,y2);
if (x1<0 || x1>639) return;
if (y1<0) y1=0;
if (y2>479) y2=479;
begline=screen+scr_linelen2*y1+x1;
for (i=y1;i<=y2;i++,begline+=scr_linelen2) *begline^=curcolor;
}
void line_32(int x,int y,int xs,int ys)
{
if (xs==0) {ver_line32(x,y,y+ys);return;}
if (ys==0) {hor_line32(x,y,x+xs);return;}
STOP();
}
void char_32(word *posit,word *font,char znak)
//#pragma aux char_32 parm [edi] [esi] [eax] modify [eax ebx ecx edx]
{
__asm
{
mov edi,posit;
mov esi,font;
mov al,znak
;edi - pozice na obrazovce
;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chrend
add esi,eax
lodsw
xor dl,dl ;dl - je citac transparetnich pozic
mov cx,ax ;cl - XRES, ch - YRES
chr6: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci
mov dh,ch ;dh - bude citac radku
chr5: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt
jnz chr1 ;jinak je dalsi bod jenom transparetni
lodsb ;cti barvu
or al,al ;pokud je 0 pak je transparetni
jz chr2 ;preskoc kresleni
cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech
jnc chr3 ;(viz FONTEDIT.DOC). Pak se podle toho zarid
and eax,0ffh;v eax jen dolnich 8 bitu
dec al
mov ax,short ptr charcolors[EAX*2] ;vyjmi barvu
cmp ax,0xffff ;0xffff je barva ktera se nekresli;
jz chr4 ;
mov [ebx],ax;zobraz ji na obrazovce
jmp chr4 ;a skoc na konec smycky
chr3: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator.
jz chrend ;V tom pripade KONEC
sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic
mov dl,al ;uloz je do citace
chr1: dec dl ;pro kazdou pozici to dl odecti dokud neni 0
chr2:
chr4: add ebx,scr_linelen;dalsi radka
dec dh ;odecti citac radek
jnz chr5 ;dokud neni nula
add edi,2 ;dalsi sloupec
dec cl ;odecti citac sloupcu
jnz chr6 ;dokud neni nula
chrend: ;konec
}
}
void char2_32(word *posit,word *font,char znak)
//#pragma aux char2_32 parm [edi] [esi] [eax] modify [eax ebx ecx edx]
{
__asm
{
mov edi,posit
mov esi,font
mov al,znak
;edi - pozice na obrazovce
;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chr2end
add esi,eax
lodsw
xor dl,dl ;dl - je citac transparetnich pozic
mov cx,ax ;cl - XRES, ch - YRES
chr26: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci
mov dh,ch ;dh - bude citac radku
chr25: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt
jnz chr21 ;jinak je dalsi bod jenom transparetni
lodsb ;cti barvu
or al,al ;pokud je 0 pak je transparetni
jz chr22 ;preskoc kresleni
cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech
jnc chr23 ;(viz FONTEDIT.DOC). Pak se podle toho zarid
and eax,0ffh;v eax jen dolnich 8 bitu
dec al
mov ax,charcolors[EAX*2] ;vyjmi barvu
push ebx
mov [ebx],ax;zobraz ji na obrazovce
mov [ebx+2],ax;zobraz ji na obrazovce
add ebx,scr_linelen
mov [ebx],ax;zobraz ji na obrazovce
mov [ebx+2],ax;zobraz ji na obrazovce
pop ebx
jmp chr24 ;a skoc na konec smycky
chr23: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator.
jz chr2end ;V tom pripade KONEC
sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic
mov dl,al ;uloz je do citace
chr21: dec dl ;pro kazdou pozici to dl odecti dokud neni 0
chr22:
chr24: add ebx,scr_linelen;dalsi radka
add ebx,scr_linelen
dec dh ;odecti citac radek
jnz chr25 ;dokud neni nula
add edi,4 ;dalsi sloupec
dec cl ;odecti citac sloupcu
jnz chr26 ;dokud neni nula
chr2end: ;konec
}
}
/* public charsize_
charsize_: ;esi - ukazatel na font
;al - znak
and eax,0ffh
mov ax,[esi][eax*2]
or ax,ax
jz chsend
add esi,eax
lodsw
chsend: and eax,0ffffh
ret*/

0
libs/bios.h Normal file
View file

82
libs/bldicons.c Normal file
View file

@ -0,0 +1,82 @@
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include "memman.h"
#include "pcx.h"
FILE *src,*trg,*scr;
#define IKNNAME "IKONY%02d.LIB"
#define IKONSINLIB 17
#define PCXSIZE (2+2+2+512+45*55)
int icount=6;
char szBuff[65536];
void Error(char *text,char *param)
{
printf(text,param);
puts("");
exit(1);
}
void ReadScript(char *script)
{
int i;
int j=0;
char *pcx;
unsigned short *wpcx;
scr=fopen(script,"rt");
if (scr==NULL) Error("Nemohu otevrit soubor: %s",script);
i=fscanf(scr,"%s",szBuff);
while (i!=EOF)
{
if (open_pcx(szBuff,A_8BIT,&pcx)==-1) Error("Nemohu pracovat se souborem: %s",szBuff);
wpcx=(unsigned short *)pcx;
if (wpcx[0]!=45 && wpcx[1]!=55) Error("Ikona musi mit rozmety 45x55. Soubor: %s",szBuff);
if (j==0)
{
sprintf(szBuff,IKNNAME,icount++);
printf("Sestavuji soubor %s\n",szBuff);
trg=fopen(szBuff,"wb");
if (trg==NULL) Error("Nelze zapisovat do souboru %s",szBuff);
}
if (!fwrite(pcx,PCXSIZE,1,trg)) Error("Chyba nastala pri zapisu do souboru %s",szBuff);
free(pcx);
j++;
if (j==18)
{
fclose(trg);
j=0;
}
i=fscanf(scr,"%s",szBuff);
}
if (j!=0)
{
void *p;
int s;
p=malloc(s=(18-j)*PCXSIZE);
memset(p,0,s);
fwrite(p,s,1,trg);
}
fcloseall();
}
void Help()
{
Error("Pouziti: \n"
"\n"
"BLDICONS <script>\n"
"\n"
"Parametrem programu je jmeno souboru, ktery obsahuje seznam vsech ikon\n"
"(tj. soubory *.pcx). Ikony musi mit rozmery 45x55.\n"
"Vystupem programu jsou soubory typu *.lib, ktere je nutne presunout do\n"
"spravneho adresare.\n"
,NULL);
}
void main(int argc,char **argv)
{
if (argc==1) Help();
puts("**Pracuji**");
ReadScript(argv[1]);
puts("**Hotovo**");
}

118
libs/bmouse.c Normal file
View file

@ -0,0 +1,118 @@
#include <skeldal_win.h>
#include "types.h"
#include "bgraph.h"
#include "event.h"
#include "devices.h"
#include "bmouse.h"
#include <stdio.h>
char visible=0;
MS_EVENT ms_last_event;
integer h_x,h_y=0;
void ukaz_mysku()
{
if (!visible) return;
visible--;
if (!visible)
{
show_ms_cursor(ms_last_event.x-h_x,ms_last_event.y-h_y);
}
}
void schovej_mysku()
{
if (!visible)
hide_ms_cursor();
visible++;
}
void zobraz_mysku()
{
visible=1;
ukaz_mysku();
}
void ms_idle_event(EVENT_MSG *info,void *user_data)
{
void *i;MS_EVENT x;
user_data;info;
if (info->msg==E_WATCH)
{
*otevri_zavoru=1;
get_ms_event(&x);
if (x.event)
{
ms_last_event=x;
i=&ms_last_event;
*otevri_zavoru=1;
send_message(E_MOUSE,i);
}
}
}
void ms_draw_event(EVENT_MSG *info,void *user_data)
{
MS_EVENT *ms_ev;
user_data;
if (info->msg==E_MOUSE)
{
ms_ev=get_mouse(info);
if (ms_ev->event_type & 1)
if (!visible) move_ms_cursor(ms_ev->x-h_x,ms_ev->y-h_y,0);
}
}
void update_mysky(void)
{
MS_EVENT x;
get_ms_event(&x);
if (x.event)
{
ms_last_event=x;
}
if(!visible) move_ms_cursor(x.x-h_x,x.y-h_y,0);
}
char je_myska_zobrazena()
{
return !visible;
}
void set_ms_finger(int x,int y)
{
h_x=x;
h_y=y;
}
void *mouse()
{
send_message(E_ADD,E_WATCH,ms_idle_event);
send_message(E_ADD,E_MOUSE,ms_draw_event);
return NULL;
}
short init_mysky()
{
// i=install_mouse_handler();
// hranice_mysky(0,0,639,479);
visible=1;
send_message(E_INIT,mouse);
return 0;
}
short done_mysky()
{
// i=deinstall_mouse_handler();
send_message(E_DONE,E_WATCH,ms_idle_event);
send_message(E_DONE,E_MOUSE,ms_draw_event);
return 0;
}

20
libs/bmouse.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef __BMOUSE_H
#define __BMOUSE_H
#include "event.h"
#include "devices.h"
#define get_mouse(info) ((MS_EVENT *)(*(long *) info->data))
extern MS_EVENT ms_last_event;
short init_mysky();
short done_mysky();
void ukaz_mysku();
void schovej_mysku();
void zobraz_mysku();
void set_ms_finger(int x,int y);
void update_mysky(void);
char je_myska_zobrazena();
#endif

233
libs/bmp2hi.c Normal file
View file

@ -0,0 +1,233 @@
#include <stdio.h>
#include "types.h"
FILE *bmp;
long xsize,ysize,nsize,xcor;
char bmptype;
char *buff,*buff2;
char filename[]="sipka.bmp";
char nfilename[256];
word newpalette[256];
word palshadow[5][256];
char genshadow=0;
int load_file(char *filename)
{
long size;
bmp=fopen(filename,"rb");
if (!bmp) return -1;
fseek(bmp,0,SEEK_END);
size=ftell(bmp);
fseek(bmp,0,SEEK_SET);
buff=(void *)malloc(size);
fread(buff,1,size,bmp);
fclose(bmp);
return 0;
}
void get_bmp_header()
{
long *p_long;
p_long=(long *)(buff+18);
xsize=*p_long;
p_long=(long *)(buff+22);
ysize=*p_long;
bmptype=*(buff+0x1c);
if (bmptype==8)
xcor=((xsize+3)/4)*4;
}
int alloc_buffer()
{
if (bmptype==24)
nsize=xsize*ysize*2;
else
nsize=xsize*ysize;
buff2=(void *)malloc(nsize);
if (buff2==NULL) return -1;
return 0;
}
void conv_hicolor()
{
char r,g,b;
short hi;
char *s,*s1,*t;
long x,y;
s=(buff+0x36+xsize*(ysize-1)*3);
t=buff2;
for(y=0;y<ysize;y++)
{
s1=s;
for(x=0;x<xsize;x++)
{
b=*(s1++)>>3;
g=*(s1++)>>3;
r=*(s1++)>>3;
hi=(r<<10)+(g<<5)+b;
*(short *)t=hi;
t+=2;
}
s-=xsize*3;
}
bmptype=15;
}
int save_file_hi(char *newname)
{
bmp=fopen(newname,"wb");
if (!bmp) return -1;
fwrite(&xsize,1,2,bmp);
fwrite(&ysize,1,2,bmp);
fwrite(&bmptype,1,2,bmp);
fwrite(buff2,1,nsize,bmp);
fclose(bmp);
return 0;
}
void pripona(char *input,char *prip,char *output)
{
short i,p;
char *ch;
i=0;p=0;ch=input;
while (*ch)
{
if (*(ch++)=='.') p=i;
i++;
}
if (!p) p=i;
ch=input;
for(i=0;i<p;i++) *(output++)=*(ch++);
*(output++)='.';
while (*prip) *(output++)=*(prip++);
*(output++)='\0';
}
void conv_palette()
{
char i,*bt;
char r,g,b;
short hi;
bt=buff;
bt+=54;i=0;
do
{
b=*(bt++)>>3;
g=*(bt++)>>3;
r=*(bt++)>>3;
hi=(r<<10)+(g<<5)+b;
bt++;
newpalette[i]=hi;
}
while (++i);
}
void palette_shadow(int tr,int tg,int tb)
{
char i,j,*bt;
char r,g,b;
short hi;
for (j=0;j<5;j++)
{
bt=buff;
bt+=54;i=0;
do
{
b=(tb+(*(bt++)-tb)*(5-j)/5)>>3;
g=(tg+(*(bt++)-tg)*(5-j)/5)>>3;
r=(tr+(*(bt++)-tr)*(5-j)/5)>>3;
hi=(r<<10)+(g<<5)+b;
bt++;
palshadow[j][i]=hi;
}
while (++i);
}
bmptype=0x28;
}
void conv_256color()
{
char *s,*s1,*t;
long x,y;
s=(buff+0x36+1024+xcor*(ysize-1));
t=buff2;
for(y=0;y<ysize;y++)
{
s1=s;
for(x=0;x<xsize;x++) *t++=*s1++;
s-=xcor;
}
bmptype=8;
}
int save_file_256(char *newname)
{
bmp=fopen(newname,"wb");
if (!bmp) return -1;
fwrite(&xsize,1,2,bmp);
fwrite(&ysize,1,2,bmp);
if (genshadow)
{
fwrite(&bmptype,1,1,bmp);
bmptype=0x1;
fwrite(&bmptype,1,1,bmp);
fwrite(palshadow,1,sizeof(palshadow),bmp);
}
else
{
fwrite(&bmptype,1,1,bmp);
bmptype=0;
fwrite(&bmptype,1,1,bmp);
fwrite(newpalette,1,sizeof(newpalette),bmp);
}
fwrite(buff2,1,nsize,bmp);
fclose(bmp);
return 0;
}
void help()
{
printf("Usage:\n\n BMP2HI filename.bmp [/p] \n");
printf("If type of BMP is 256 colors use /p for generate palette shadowing.\n");
return;
}
void main(int argc, const char *argv[])
{
if (argc<2)
{
help();
return;
}
if (argc==3 && (argv[2][1]=='p' || argv[2][1]=='P')) genshadow=1;
if (load_file((char *)argv[1])) return;
get_bmp_header();
if (bmptype!=24 && bmptype!=8) return;
if (alloc_buffer()) return;
if (bmptype==24)
{
conv_hicolor();
pripona((char *)argv[1],"HI",nfilename);
save_file_hi(nfilename);
}
else
{
conv_256color();
if (genshadow) palette_shadow(0,0,0); else conv_palette();
pripona((char *)argv[1],"HI",nfilename);
save_file_256(nfilename);
}
printf("Konverze z %s na %s uspesna",argv[1],nfilename);
return ;
}

181
libs/cspells.c Normal file
View file

@ -0,0 +1,181 @@
#include <stdio.h>
#include <process.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "types.h"
#define PGM_SIZE 200000
#define TAB_SIZE 512
typedef struct tkouzlo
{
word num,um,mge;
word pc;
short owner,accnum; //accnum = akumulacni cislo, owner = kdo kouzlo seslal
int start;
short cil;
char povaha;
word backfire;
word wait; //wait - cekani pocet animaci
word delay; //delay - cekani pocet kol
char traceon; //tracovani cile.
char spellname[30];
}TKOUZLO;
TKOUZLO kouzla_tab[TAB_SIZE];
char program[PGM_SIZE];
char *pgm;
FILE *source;
FILE *target;
int cur_spell;
char global_name[256];
void init(char *filename )
{
pgm=program;
source=fopen(filename,"r");
cur_spell=0;
if (source==NULL)
{
printf("INIT: Nemohu otevrit soubor %s \n",filename);
exit(1);
}
}
void add_prog_command(int i)
{
*pgm++=i;
}
void add_prog_word(int i)
{
*(short *)pgm=i;
pgm+=2;
}
void add_prog_string(char *c)
{
if (*c==32) c++;
strcpy(pgm,c);
pgm+=strlen(c)+1;
}
int build_tables()
{
int num,i,num2;
char s[256];
do
{
i=fscanf(source,"%d",&num);
if (i==1)
{
switch (num)
{
case 128:while (fgetc(source)!='\n');
fgetc(source);
i=fscanf(source,"%[^\n]",global_name);
strncpy(kouzla_tab[cur_spell].spellname,global_name,29);
printf("(%3d, 0x%05X) %s\n",cur_spell, kouzla_tab[cur_spell].start,global_name);
break;
case 129:add_prog_command(0xff);
i=fscanf(source,"%d",&cur_spell);
if (i==1)
{
kouzla_tab[cur_spell].start=(pgm-program)+sizeof(kouzla_tab);
}
break;
case 132:i=fscanf(source,"%d",&num);kouzla_tab[cur_spell].cil=num;break;
case 133:i=fscanf(source,"%d",&num);kouzla_tab[cur_spell].um=num;break;
case 134:i=fscanf(source,"%d",&num);kouzla_tab[cur_spell].mge=num;break;
case 144:i=fscanf(source,"%d",&num);kouzla_tab[cur_spell].backfire=num;break;
case 145:i=fscanf(source,"%d",&num);kouzla_tab[cur_spell].povaha=num;break;
case 155:i=fscanf(source,"%d",&num);kouzla_tab[cur_spell].accnum=num;break;
case 149:
case 164:
case 148:add_prog_command(num);i=fscanf(source,"%s",s);add_prog_string(s+1);break;
case 192:add_prog_command(num);break;
default: if (num==142) kouzla_tab[cur_spell].traceon|=1;
add_prog_command(num);i=fscanf(source,"%d",&num2);add_prog_word(num2);
if (num==146 && num2==12) kouzla_tab[cur_spell].traceon|=2;
break;
}
}
if (i==0)
{
printf("COMPILE: Chyba pri kompilaci kouzla '%s' \n",global_name);
exit(0);
}
}
while(i!=EOF);
return pgm-program;
}
void save_tab(char *name)
{
target=fopen(name,"wb");
if (target==NULL)
{
printf("SAVE: Chyba pri ukladani souboru %s \n",name);
exit(0);
}
fwrite(kouzla_tab,1,sizeof(kouzla_tab),target);
fwrite(program,1,pgm-program,target);
fclose(target);
}
const char *GetLexLibPath()
{
static char c[MAX_PATH];
char *z;
GetModuleFileName(0,c,MAX_PATH);
z=strrchr(c,'\\')+1;
strcpy(z,"lex_lib.exe");
return c;
}
main(int argc,char *argv[])
{
int codesize;
char *z;
printf("%d\n",sizeof(TKOUZLO));
if (argc<2)
{
puts("Tento program vyzaduje jmeno souboru, ve kterem se nalezaji\n"
"platne definice kouzel pro hru BRANY SKELDALU v 1.0");
exit(0);
}
puts("");
puts("Prob¡h  kompilace:");
puts(" Spouçt¡m program LEX_LIB.EXE\n");
putenv("DOS4G=QUIET");
z=(char *)malloc(strlen(argv[1])+10);
sprintf(z,"\"%s\"",argv[1]);
if (spawnlp(P_WAIT,GetLexLibPath(),"lex_lib.exe",z,"temp.$$$",NULL))
exit(1);
free(z);
if (errno)
{
puts("Nemohu spustit program lex_lib.exe");
exit(1);
}
puts("Byla kompilov na tato kouzla:");
puts("¬¡slo, zaŸ tek, jmeno:");
puts("======================");
memset(kouzla_tab,0,sizeof(kouzla_tab));
init("temp.$$$");
codesize=build_tables();
add_prog_command(0xff);
fclose(source);
save_tab("kouzla.dat");
remove("temp.$$$");
puts("Kompilace £spØçn ...");
printf("Dlka k¢du: %d (+%d)",codesize,sizeof(kouzla_tab));
}

66
libs/devices.c Normal file
View file

@ -0,0 +1,66 @@
#include <skeldal_win.h>
#include "types.h"
#include <stdio.h>
#include <dos.h>
//#include <i86.h>
#include <bios.h>
#include "event.h"
#include "devices.h"
#include <time.h>
/* Data touched at mouse callback time -- they are in a structure to
simplify calculating the size of the region to lock.
*/
extern MS_EVENT win_mouseEvent;
TMS_BASIC_INFO ms_basic_info={0};
static char ms_keys;
void get_ms_event(MS_EVENT *event)
{
CheckMessageQueue();
*event=win_mouseEvent;
win_mouseEvent.event=0;
}
char cz_table_1[]=" 1!3457­908+,-./+ˆ¨‡©‘˜ ¡\"?=:_2ABCDEFGHIJKLMNOPQRSTUVWXYZ£\\)6=;abcdefghijklmnopqrstuvwxyz/|(; ";
char cz_table_2[]=" !\"#$%&'()*+,-./0123456789:;<=>?@<40>BCD<43>FGHJKŠMN•PQ«ST—VWX<57>Z[\\]^_` bcdfgh¡jk<6A>mn¢pqªst£vwx˜z{|}~ ";
char cz_table_3[]=" !\"#$%&'()*+,-./0123456789:;<=>?@AB€…‰FGHIJKœM¥§PQž†¦VWXY[\\]^_`ab‡ƒˆfghijkŒm¤“pq©¨Ÿvwxy{|}~ ";
char *cz_key_tabs[]={cz_table_1,cz_table_2,cz_table_3};
void keyboard(EVENT_MSG *msg,void *user_data)
{
int i;
static char cz_mode=0;
char c,d;
msg;user_data;
if (msg->msg==E_WATCH)
{
*otevri_zavoru=1;
if (!_bios_keybrd(_KEYBRD_READY)) return;
i=_bios_keybrd(_KEYBRD_READ);
d=i>>8;
c=i & 0xff;
if (c=='+' && d<55 && !cz_mode) cz_mode=2;
else if (c=='=' && d<55 && !cz_mode) cz_mode=1;
else if (c>32 && c<127 && d<=53)
{
c=cz_key_tabs[cz_mode][c-32];
i=d;
i=(i<<8)+c;
send_message(E_KEYBOARD,i);
cz_mode=0;
}
else
send_message(E_KEYBOARD,i);
}
}
char ms_get_keycount()
{
return ms_keys;
}

35
libs/devices.h Normal file
View file

@ -0,0 +1,35 @@
#ifndef __DEVICES_H
#define __DEVICES_H
#include "types.h"
#include "event.h"
typedef struct tms_basic_info
{
int mouse_event;
unsigned short mouse_code;
unsigned short mouse_bx;
unsigned short mouse_cx;
unsigned short mouse_dx;
signed short mouse_si;
signed short mouse_di;
}TMS_BASIC_INFO;
typedef struct ms_event
{
char event;
word x,y;
char tl1,tl2,tl3;
word event_type;
}MS_EVENT;
extern TMS_BASIC_INFO ms_basic_info;
extern char ms_fake_mode;
//int install_mouse_handler();
//int deinstall_mouse_handler();
//void hranice_mysky(int x1,int y1,int x2,int y2);
void get_ms_event(MS_EVENT *event);
int lock_region (void *address, unsigned length);
void keyboard(EVENT_MSG *msg,void *user_data);
char ms_get_keycount();
#endif

76
libs/doserr.asm Normal file
View file

@ -0,0 +1,76 @@
.model small
.386
_DATA segment byte public 'DATA' use32
public _call_proc
_call_proc dd ?
old_stack dd ?
old_stack_seg dw ?
new_stack_pos dd ?
new_stack_seg dw ?
_DATA ends
DGROUP group _DATA
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
extern _dos_setvect_:proc
extern __GETDS:proc
public dos_int24_
dos_int24_:cld
push ds
call __GETDS
mov old_stack,esp
mov old_stack_seg,ss
lss esp,new_stack_pos
push es
push fs
push gs
push ebx
push ecx
push edx
push edi
push esi
push ebp
mov ax,ds
mov es,ax
mov fs,ax
mov gs,ax
mov dl,ah
mov bl,al
mov eax,edi
call _call_proc
pop ebp
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop gs
pop fs
pop es
lss esp,old_stack
pop ds
iretd
public install_dos_error_
;eax - procedura
;edx - stack
install_dos_error_:
mov _call_proc,eax
mov new_stack_pos,edx
mov new_stack_seg,ss
mov ebx,offset dos_int24_
mov cx,cs
mov eax,24h
call _dos_setvect_
ret
_TEXT ends
End

18
libs/doserr.h Normal file
View file

@ -0,0 +1,18 @@
/*void install_dos_error(void *,void *);
#pragma aux install_dos_error parm [eax][edx] modify [ebx ecx esi edi]
*/
#define _ERR_WRITE 1
#define _ERR_SYS 0
#define _ERR_FAT 1
#define _ERR_DIR 2
#define _ERR_DATA 3
#define _ERR_EFAIL 8
#define _ERR_ERETRY 16
#define _ERR_EIGNORE 32
#define _ERR_NOTDISK 128
#define _ERR_IGNORE 0
#define _ERR_RETRY 1
#define _ERR_ABORT 2
#define _ERR_FAIL 3

885
libs/engine1.c Normal file
View file

@ -0,0 +1,885 @@
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <bios.h>
#include "memman.h"
#include "bgraph.h"
#define VIEW_SIZE_X 640
#define VIEW_SIZE_Y 360
#define TAB_SIZE_X 640
#define TAB_SIZE_Y 600
#define MIDDLE_X 320
#define MIDDLE_Y 112
#define TXT_SIZE_Y 320
#define TXT_SIZE_X_3D 74
#define TXT_SIZE_X 500
#define VIEW3D_X 2
#define VIEW3D_Z 4
#define START_X1 357
#define START_Y1 305
#define START_X2 357
#define START_Y2 -150
#define FACTOR_3D 3.33333
#define ZOOM_PHASES 9
#define C_YMAP_SIZE 79
#define F_YMAP_SIZE 176
#define CF_XMAP_SIZE 5
#define MISTNOSTI 40
typedef struct zoominfo
{
void *startptr, *texture;
long texture_line,line_len;
long *xtable;
short *ytable;
word *palette;
word ycount;
word xmax;
}ZOOMINFO;
typedef struct t_info_y
{
long drawline; //ukazatel na radku na ktere bude stena zacinat
word vert_size; //konecna velikost steny, pokud ma pocatecni velikost TXT_SIZE_Y
word vert_total; //maximalni velikost textury aby jeste nepresahla obrazovku
short zoom_table[TAB_SIZE_Y]; //tabulka pro zoomovaci rutiny
}T_INFO_Y;
typedef struct t_info_x_3d
{
char used; // 1 pokud je tato strana videt
word xpos; //bod od leveho okraje
word txtoffset; //posunuti x vuci texture
word point_total; //rozdil mezi levym prednim a levym zadnim okrajem postranni steny (v adresach)
long zoom_table[MIDDLE_X]; //zoomovaci tabulka pro osu x pro postranni steny
}T_INFO_X_3D;
typedef struct t_info_x
{
char used; // 1 pokud je tato strana videt
word xpos; //bod od leveho okraje
word xpos2; //totez ale pro pravou stranu
word txtoffset; //posunuti x vuci texture
word max_x; //pocet viditelnych bodu z textury
word point_total; //celkovy pocet adres mezi levym a pravym okrajem
long zoom_table[VIEW_SIZE_X]; //zoomovaci tabulka pro osu x pro kolme steny
}T_INFO_X;
typedef struct t_floor_map
{
long lineofs,linesize,counter;
}T_FLOOR_MAP;
typedef struct all_view
{
T_INFO_Y y_table[VIEW3D_Z+1];
T_INFO_X_3D z_table[VIEW3D_X][VIEW3D_Z];
T_INFO_X x_table[VIEW3D_X][VIEW3D_Z+1];
T_FLOOR_MAP f_table[CF_XMAP_SIZE][F_YMAP_SIZE];
T_FLOOR_MAP c_table[CF_XMAP_SIZE][C_YMAP_SIZE];
}ALL_VIEW;
typedef struct t_point
{
int x,y;
}T_POINT;
typedef T_POINT t_points[VIEW3D_X+1][2][VIEW3D_Z+1];
typedef integer TESTMAP_IT[4];
typedef TESTMAP_IT TESTMAP[MISTNOSTI];
TESTMAP mapa;
char renderstop[MISTNOSTI];
char dirs[2];
t_points points;
struct all_view showtabs;
ZOOMINFO zoom;
extern char datapath[]="";
char zooming_xtable[ZOOM_PHASES][VIEW_SIZE_X];
short zooming_ytable[ZOOM_PHASES][VIEW_SIZE_Y];
short zooming_points[ZOOM_PHASES][4]
={
{620,349,10,3},
{600,338,20,7},
{580,327,30,11},
{560,316,40,14},
{540,305,50,18},
{520,293,60,21},
{500,282,70,25},
{480,271,80,28},
{460,259,90,31}
};
int zooming_step=1;
int rot_phases=2,rot_step=150;
int yreq;
void sikma_zleva(void);
#pragma aux sikma_zleva parm modify [EAX EBX ECX EDX ESI EDI]
void sikma_zprava(void);
#pragma aux sikma_zprava parm modify [EAX EBX ECX EDX ESI EDI]
void zooming32(void *source,void *target,void *xlat,long xysize);
#pragma aux zooming32 parm [ESI][EDI][EBX][ECX] modify [EAX EDX]
void zooming_lo(void *source,void *target,void *xlat,long xysize);
#pragma aux zooming_lo parm [ESI][EDI][EBX][ECX] modify [EAX EDX]
void zooming256(void *source,void *target,void *xlat,long xysize);
#pragma aux zooming256 parm [ESI][EDI][EBX][ECX] modify [EAX EDX]
void scroll_support_32(void *lbuf,void *src1,void *src2,int size1);
#pragma aux scroll_support_32 parm [EDI][ESI][EDX][ECX] modify [EAX]
void scroll_support_256(void *lbuf,void *src1,void *src2,int size1,void *xlat);
#pragma aux scroll_support_256 parm [EDI][ESI][EDX][ECX][EBX] modify [EAX];
void fcdraw(void *source,void *target, void *table);
#pragma aux fcdraw parm [EDX][EBX][EAX] modify [ECX ESI EDI];
void *p,*p2,*pozadi,*podlaha,*strop,*sit;int i;
void (*zooming)(void *source,long target,void *xlat,long xysize);
void (*turn)(long lbuf,void *src1,void *src2,int size1);
word *buffer_2nd;
char debug=0,nosides=0,nofloors=0,drwsit=0;
void zooming1(void *source,long target,void *xlat,long xysize)
{
zooming32(source,lbuffer+target,xlat,xysize);
}
void zooming2(void *source,long target,void *xlat,long xysize)
{
zooming256(source,lbuffer+(target>>1),xlat,xysize);
}
void zooming3(void *source,long target,void *xlat,long xysize)
{
zooming_lo(source,lbuffer+target,xlat,xysize);
}
void turn1(long lbuf,void *src1,void *src2,int size1)
{
scroll_support_32(lbuf+lbuffer,src1,src2,size1);
}
void turn2(long lbuf,void *src1,void *src2,int size1)
{
scroll_support_256((lbuf>>1)+lbuffer,src1,src2,size1,xlatmem);
}
void calc_points(void)
{
int i,j,x1,y1,x2,y2;
for (j=0;j<VIEW3D_X+1;j++)
{
x1=START_X1+2*START_X1*j;y1=START_Y1;
x2=START_X2+2*START_X1*j;y2=START_Y2;
for (i=0;i<VIEW3D_Z+1;i++)
{
points[j][0][i].x=x1;
points[j][0][i].y=y1;
points[j][1][i].x=x2;
points[j][1][i].y=y2;
x2=(int)(x2-x2/FACTOR_3D);
y2=(int)(y2-y2/FACTOR_3D);
x1=(int)(x1-x1/FACTOR_3D);
y1=(int)(y1-y1/FACTOR_3D);
}
}
}
void calc_x_buffer(long *ptr,long txt_size_x, long len,long total)
{
int i,j,old;
old=-1;
for (i=0;i<total;i++)
{
j=(i*txt_size_x)/len;
*(ptr++)=(j-old-1);
old=j;
}
}
void calc_y_buffer(short *ptr,long txt_size_y, long len,long total)
{
int i,j,old;
old=-1;
for (i=0;i<total;i++)
{
j=(i*txt_size_y)/len;
*(ptr++)=(j-old);
old=j;
}
}
void create_tables(void)
{
int x,y;
for (y=0;y<VIEW3D_Z+1;y++)
{
showtabs.y_table[y].vert_size=points[1][0][y].y-points[1][1][y].y;
showtabs.y_table[y].vert_total=(points[1][0][y].y+MIDDLE_Y);
showtabs.y_table[y].drawline=(VIEW_SIZE_X*(points[1][0][y].y+MIDDLE_Y))+SCREEN_OFFSET;
calc_y_buffer(&showtabs.y_table[y].zoom_table,TXT_SIZE_Y,showtabs.y_table[y].vert_size,TAB_SIZE_Y);
}
for (y=0;y<VIEW3D_Z;y++)
for (x=0;x<VIEW3D_X;x++)
{
int rozdil1,rozdil2;
if (points[x][0][y+1].x>MIDDLE_X) showtabs.z_table[x][y].used=0;
else
{
showtabs.z_table[x][y].used=1;
rozdil1=points[x][0][y].x-points[x][0][y+1].x;
rozdil2=rozdil1-MIDDLE_X+points[x][0][y+1].x;
if (rozdil2<0)
{
showtabs.z_table[x][y].xpos=MIDDLE_X-points[x][0][y].x;
showtabs.z_table[x][y].txtoffset=0;
}
else
{
showtabs.z_table[x][y].xpos=0;
showtabs.z_table[x][y].txtoffset=(TXT_SIZE_X_3D*rozdil2/rozdil1);
}
showtabs.z_table[x][y].point_total=rozdil1;
calc_x_buffer(&showtabs.z_table[x][y].zoom_table,TXT_SIZE_X_3D,rozdil1,MIDDLE_X);
}
}
for (y=0;y<VIEW3D_Z+1;y++)
for (x=0;x<VIEW3D_X;x++)
{
int rozdil1,rozdil2;
{
showtabs.x_table[x][y].used=1;
rozdil1=points[1][0][y+1].x-points[0][0][y+1].x;
rozdil2=-MIDDLE_X+points[x][0][y+1].x;
if (rozdil2<0)
{
showtabs.x_table[x][y].xpos=MIDDLE_X-points[x][0][y+1].x;
showtabs.x_table[x][y].txtoffset=0;
showtabs.x_table[x][y].max_x=rozdil1;
}
else
{
showtabs.x_table[x][y].xpos=0;
showtabs.x_table[x][y].txtoffset=(TXT_SIZE_X*rozdil2/rozdil1);
showtabs.x_table[x][y].max_x=MIDDLE_X-points[x-1][0][y+1].x;
}
if (x!=0)showtabs.x_table[x][y].xpos2=VIEW_SIZE_X-(showtabs.x_table[x][y].xpos+showtabs.x_table[x][y].max_x);
showtabs.x_table[x][y].point_total=rozdil1;
calc_x_buffer(&showtabs.x_table[x][y].zoom_table,TXT_SIZE_X,rozdil1,VIEW_SIZE_X);
}
}
for(x=0;x<CF_XMAP_SIZE;x++)
for(y=0;y<F_YMAP_SIZE;y++)
{
int xl,xr,y1,yp,strd;
strd=CF_XMAP_SIZE>>1;
y1=(VIEW_SIZE_Y-y)-MIDDLE_Y;
yp=1;while (points[0][0][yp].y>y1) yp++;
if (x<strd)
{
xl=-points[strd-x][0][0].x;xr=-points[strd-x-1][0][0].x;
}
else if (x==strd)
{
xl=-points[0][0][0].x;xr=+points[0][0][0].x;
}
else if (x>strd)
{
xl=+points[x-strd-1][0][0].x;xr=+points[x-strd][0][0].x;
}
y1=(VIEW_SIZE_Y-y)-MIDDLE_Y;
xl=xl*(y1+1)/points[0][0][0].y+MIDDLE_X;
xr=xr*(y1+1)/points[0][0][0].y+MIDDLE_X;
if (xl<0) xl=0;if (xr<0) xr=0;
if (xl>639) xl=639;if (xr>639) xr=639;
showtabs.f_table[x][y].lineofs=(y1+MIDDLE_Y)*1280+xl*2;
showtabs.f_table[x][y].linesize=xr-xl;
showtabs.f_table[x][y].counter=(y1-points[0][0][yp].y);
}
for(x=0;x<CF_XMAP_SIZE;x++)
for(y=0;y<C_YMAP_SIZE;y++)
{
int xl,xr,y1,yp,strd;
strd=CF_XMAP_SIZE>>1;
y1=y-MIDDLE_Y;
yp=1;while (points[0][1][yp].y<y1) yp++;
if (x<strd)
{
xl=-points[strd-x][1][0].x;xr=-points[strd-x-1][1][0].x;
}
else if (x==strd)
{
xl=-points[0][1][0].x;xr=+points[0][1][0].x;
}
else if (x>strd)
{
xl=+points[x-strd-1][1][0].x;xr=+points[x-strd][1][0].x;
}
xl=xl*(y1-1)/points[0][1][0].y+MIDDLE_X;
xr=xr*(y1-1)/points[0][1][0].y+MIDDLE_X;
if (xl<0) xl=0;if (xr<0) xr=0;
if (xl>639) xl=639;if (xr>639) xr=639;
showtabs.c_table[x][y].lineofs=(y1+MIDDLE_Y)*1280+xl*2;
showtabs.c_table[x][y].linesize=xr-xl;
showtabs.c_table[x][y].counter=points[0][1][yp].y-y1;
}
}
void calc_zooming(char *buffer,int dvojice,int oldsiz)
{
int poz,roz,i,x;
poz=-2;
for(i=0;i<dvojice;i++)
{
x=(i*oldsiz/dvojice);
roz=x-poz;
if (roz>2) roz=2;
if (roz<1) roz=1;
if (roz==1) *buffer++=1; else *buffer++=0;
poz+=roz;
}
}
void create_zooming(void)
{
int i,j;
for (j=0;j<ZOOM_PHASES;j++)
{
calc_zooming(&zooming_xtable[j],320,zooming_points[j][0]);
calc_y_buffer(&zooming_ytable[j],zooming_points[j][1],360,360);
for(i=0;i<360;i++) zooming_ytable[j][i]*=1280;
}
/* calc_zooming(&zooming_xtable[0],320,570);
calc_y_buffer(&zooming_ytable[0],350,400,400);
for(i=0;i<400;i++) zooming_ytable[0][i]*=1280;
calc_zooming(&zooming_xtable[1],320,500);
calc_y_buffer(&zooming_ytable[1],320,400,400);
for(i=0;i<400;i++) zooming_ytable[1][i]*=1280;
calc_zooming(&zooming_xtable[2],320,450);
calc_y_buffer(&zooming_ytable[2],280,400,400);
for(i=0;i<400;i++) zooming_ytable[2][i]*=1280;
*/
}
void zooming_forward(void)
{
int i;
for (i=0;i<ZOOM_PHASES;i+=zooming_step)
{
zoom.xtable=(long *)&zooming_xtable[i];
zoom.ytable=(short *)&zooming_ytable[i];
zoom.texture_line=0;
zooming(screen+zooming_points[i][2]+zooming_points[i][3]*640+SCREEN_OFFSET,SCREEN_OFFSET,xlatmem,(360<<16)+320);
}
}
void zooming_backward(void)
{
int i;
for (i=ZOOM_PHASES-1;i>=0;i-=zooming_step)
{
zoom.xtable=(long *)&zooming_xtable[i];
zoom.ytable=(short *)&zooming_ytable[i];
zoom.texture_line=0;
zooming(screen+zooming_points[i][2]+zooming_points[i][3]*640+SCREEN_OFFSET,SCREEN_OFFSET,xlatmem,(360<<16)+320);
}
}
/* zoom.xtable=(long *)&zooming_xtable[0];
zoom.ytable=(short *)&zooming_ytable[0];
zoom.texture_line=0;
zooming(screen+35+25*640+SCREEN_OFFSET,lbuffer+SCREEN_OFFSET,xlatmem,(360<<16)+320);
zoom.xtable=(long *)&zooming_xtable[1];
zoom.ytable=(short *)&zooming_ytable[1];
zoom.texture_line=0;
zooming(screen+70+40*640+SCREEN_OFFSET,lbuffer+SCREEN_OFFSET,xlatmem,(360<<16)+320);
zoom.xtable=(long *)&zooming_xtable[2];
zoom.ytable=(short *)&zooming_ytable[2];
zoom.texture_line=0;
zooming(screen+95+60*640+SCREEN_OFFSET,lbuffer+SCREEN_OFFSET,xlatmem,(360<<16)+320);
*/
void turn_left()
{
word *kde1,c;
int i;
kde1=screen+SCREEN_OFFSET+70;
c=640-140;
for(i=0;i<rot_phases;i++)
{
kde1+=rot_step;
c-=rot_step;
turn(SCREEN_OFFSET,kde1,buffer_2nd+SCREEN_OFFSET+70,c);
}
}
void turn_right()
{
word *kde1,c;
int i;
kde1=screen+SCREEN_OFFSET+70+400;
c=640-140-400;
for(i=0;i<rot_phases;i++)
{
kde1-=rot_step;
c+=rot_step;
turn(SCREEN_OFFSET,kde1,buffer_2nd+SCREEN_OFFSET+70,c);
}
}
void show_cel_l(int celx,int cely,void *stena)
{
T_INFO_X_3D *x3d;
T_INFO_Y *yd;
if (nosides) return;
x3d=&showtabs.z_table[celx][cely];
yd=&showtabs.y_table[cely];
if (x3d->used)
{
zoom.startptr=buffer_2nd+(yd->drawline+x3d->xpos);
zoom.texture=(void *)((byte *)stena+256*2*5+2*2+2+x3d->txtoffset);
zoom.texture_line=*(word *)stena;
zoom.xtable=&x3d->zoom_table;
zoom.ytable=&yd->zoom_table;
zoom.palette=(word *)((byte *)stena+6+512*cely);
zoom.ycount=yd->vert_size*(*((word *)stena+1))/TXT_SIZE_Y;
if (zoom.ycount>yd->vert_total) zoom.ycount=yd->vert_total;
zoom.line_len=1280;
zoom.xmax=VIEW_SIZE_X;
sikma_zleva();
}
}
void show_cel_r(int celx,int cely,void *stena)
{
T_INFO_X_3D *x3d;
T_INFO_Y *yd;
if (nosides) return;
x3d=&showtabs.z_table[celx][cely];
yd=&showtabs.y_table[cely];
if (x3d->used)
{
zoom.startptr=buffer_2nd+(yd->drawline+639-x3d->xpos);
zoom.texture=(void *)((byte *)stena+256*2*5+2*2+2+x3d->txtoffset);
zoom.texture_line=*(word *)stena;
zoom.xtable=&x3d->zoom_table;
zoom.ytable=&yd->zoom_table;
zoom.palette=(word *)((byte *)stena+6+512*cely);
zoom.ycount=yd->vert_size*(*((word *)stena+1))/TXT_SIZE_Y;
if (zoom.ycount>yd->vert_total) zoom.ycount=yd->vert_total;
zoom.line_len=1280;
zoom.xmax=VIEW_SIZE_X;
sikma_zprava();
}
}
void show_cel2_l(int celx,int cely,void *stena)
{
T_INFO_X *x3d;
T_INFO_Y *yd;
if (nosides) return;
x3d=&showtabs.x_table[celx][cely];
yd=&showtabs.y_table[cely+1];
if (x3d->used)
{
zoom.startptr=buffer_2nd+(yd->drawline+x3d->xpos);
zoom.texture=(void *)((byte *)stena+256*2*5+2*2+2+x3d->txtoffset);
zoom.texture_line=*(word *)stena;
zoom.xtable=&x3d->zoom_table;
zoom.ytable=&yd->zoom_table;
zoom.palette=(word *)((byte *)stena+6+512*(/*cely*/+1));
zoom.ycount=yd->vert_size*(*((word *)stena+1))/TXT_SIZE_Y;
if (zoom.ycount>yd->vert_total) zoom.ycount=yd->vert_total;
zoom.xmax=x3d->max_x;
zoom.line_len=1280;
sikma_zleva();
}
}
void show_cel2_r(int celx,int cely,void *stena)
{
T_INFO_X *x3d;
T_INFO_Y *yd;
if (nosides) return;
x3d=&showtabs.x_table[celx][cely];
yd=&showtabs.y_table[cely+1];
if (x3d->used)
{
zoom.startptr=buffer_2nd+(yd->drawline+x3d->xpos2);
zoom.texture=(void *)((byte *)stena+256*2*5+2*2+2);
zoom.texture_line=*(word *)stena;
zoom.xtable=&x3d->zoom_table;
zoom.ytable=&yd->zoom_table;
zoom.palette=(word *)((byte *)stena+6+512*(cely+1));
zoom.ycount=yd->vert_size*(*((word *)stena+1))/TXT_SIZE_Y;
if (zoom.ycount>yd->vert_total) zoom.ycount=yd->vert_total;
zoom.line_len=1280;
zoom.xmax=x3d->max_x;
sikma_zleva();
}
}
void draw_floor_ceil(int celx,int cely,char f_c,void *txtr)
{
int y;
if (nofloors) return;
txtr=(void *)((word *)txtr+3);
if (f_c==0) //podlaha
{
y=(VIEW_SIZE_Y-MIDDLE_Y)-points[0][0][cely].y+1;
if (y<0) y=0;
txtr=(void *)((word *)txtr-(VIEW_SIZE_Y-F_YMAP_SIZE)*640);
fcdraw(txtr,buffer_2nd+SCREEN_OFFSET,&showtabs.f_table[celx+2][y]);
if (debug)
{
memcpy(screen,buffer_2nd,512000);
showview(0,0,0,0);
}
}
else
{
y=points[0][1][cely].y+MIDDLE_Y+1;
if (y<0) y=0;
fcdraw(txtr,buffer_2nd+SCREEN_OFFSET,&showtabs.c_table[celx+2][y]);
if (debug)
{
memcpy(screen,buffer_2nd,512000);
showview(0,0,0,0);
}
}
}
void build_map(void)
{
int i;
memset(&mapa,0xff,sizeof(mapa));
mapa[0][0]=1;
mapa[0][2]=9;
mapa[1][2]=0;
mapa[1][0]=2;
mapa[2][2]=1;
mapa[2][1]=3;
mapa[2][0]=5;
mapa[3][3]=2;
mapa[3][0]=4;
mapa[3][2]=6;
mapa[4][2]=3;
mapa[4][3]=5;
// mapa[4][0]=19;
mapa[5][1]=4;
mapa[5][2]=2;
mapa[5][3]=11;
mapa[6][0]=3;
mapa[6][1]=7;
mapa[7][3]=6;
mapa[7][1]=8;
mapa[8][3]=7;
mapa[8][0]=9;
mapa[9][2]=8;
mapa[9][0]=0;
mapa[11][1]=5;
mapa[11][3]=12;
mapa[12][1]=11;
mapa[12][2]=13;
mapa[13][0]=12;
mapa[13][3]=14;
mapa[13][2]=18;
mapa[14][1]=13;
mapa[14][3]=15;
mapa[14][2]=17;
mapa[15][1]=14;
mapa[15][2]=16;
mapa[15][0]=20;
mapa[16][0]=15;
mapa[16][1]=17;
mapa[17][3]=16;
mapa[17][0]=14;
mapa[17][1]=18;
mapa[18][3]=17;
mapa[18][0]=13;
mapa[18][2]=19;
mapa[19][0]=18;
mapa[19][2]=4;
mapa[20][2]=15;mapa[20][0]=21;
mapa[21][2]=20;mapa[21][0]=22;
mapa[22][2]=21;
for (i=22;i<40;i++)
{
if (i>22) mapa[i][3]=i-1;
if (i<38) mapa[i][1]=i+1;
if (i<34) mapa[i][0]=i+5;
if (i>26) mapa[i][2]=i-5;
}
}
void build_left(integer y,integer sector)
{
if (renderstop[sector]) return;
if (y>=VIEW3D_Z) return;
renderstop[sector]=1;
if (mapa[sector][dirs[1]]!=-1)
build_left(y+1,mapa[sector][dirs[1]]);
if (yreq!=y) return;
draw_floor_ceil(-1,y,0,podlaha);
draw_floor_ceil(-1,y,1,strop);
if (mapa[sector][dirs[0]]==-1)
show_cel_l(1,y,p);
if (mapa[sector][dirs[1]]==-1)
show_cel2_l(1,y,p2);
}
void build_right(int y,int sector)
{
if (renderstop[sector]) return;
if (y>=VIEW3D_Z) return;
renderstop[sector]=1;
if (mapa[sector][dirs[1]]!=-1)
build_right(y+1,mapa[sector][dirs[1]]);
if (yreq!=y) return;
draw_floor_ceil(1,y,0,podlaha);
draw_floor_ceil(1,y,1,strop);
if (mapa[sector][dirs[2]]==-1)
show_cel_r(1,y,p);
if (mapa[sector][dirs[1]]==-1)
show_cel2_r(1,y,p2);
}
void swap_buffs(void)
{
word *p;
p=screen;
screen=buffer_2nd;
buffer_2nd=p;
}
void build_scene(int y,int sector)
{
if (renderstop[sector]) return;
if (y>=VIEW3D_Z) return;
renderstop[sector]=1;
if (mapa[sector][dirs[0]]!=-1)
build_left(y,mapa[sector][dirs[0]]);
if (mapa[sector][dirs[2]]!=-1)
build_right(y,mapa[sector][dirs[2]]);
if (mapa[sector][dirs[1]]!=-1)
build_scene(y+1,mapa[sector][dirs[1]]);
if (yreq!=y) return;
draw_floor_ceil(0,y,0,podlaha);
draw_floor_ceil(0,y,1,strop);
if (mapa[sector][dirs[0]]==-1)
show_cel_l(0,y,p);
if (mapa[sector][dirs[2]]==-1)
show_cel_r(0,y,p);
if (mapa[sector][dirs[1]]==-1)
show_cel2_l(0,y,p2);
}
void render_scene(int sector,int dir)
{
if (nofloors || nosides || drwsit) memcpy(buffer_2nd,(void *)((char *)sit+6),screen_buffer_size);
else
memset(buffer_2nd,0x0,screen_buffer_size);
//memcpy(buffer_2nd+SCREEN_OFFSET,(void *)((char *)strop+6),640*79*2);
//memcpy(buffer_2nd+SCREEN_OFFSET+640*184,(void *)((char *)podlaha+6),640*176*2);
dirs[1]=dir;dirs[0]=(dir-1)&3;
dirs[2]=(dir+1)&3;
for (yreq=4;yreq>=0;yreq--)
{
memset(&renderstop,0,sizeof(renderstop));
build_scene(0,sector);
}
}
void chozeni(void)
{
char c; char dir=0;word sector=22;
zooming_forward();
swap_buffs();
showview(0,0,0,0);
do
{
while (_bios_keybrd(_KEYBRD_READY)) _bios_keybrd(_KEYBRD_READ);
c=_bios_keybrd(_KEYBRD_READ) >> 8;
switch (c)
{
case 'H':if (mapa[sector][dir]!=-1)
{
sector=mapa[sector][dir];
render_scene(sector,dir);
if (!debug) zooming_forward();
swap_buffs();
showview(0,0,0,0);
}break;
case 'P':if (mapa[sector][(dir+2)&3]!=-1)
{
sector=mapa[sector][(dir+2)&3];
render_scene(sector,dir);
swap_buffs();
if (!debug) zooming_backward();
showview(0,0,0,0);
}break;
case 'M':dir=(dir+1)&3;
render_scene(sector,dir);
if (!debug) turn_left();
swap_buffs();
showview(0,0,0,0);
break;
case 'K':dir=(dir-1)&3;
render_scene(sector,dir);
swap_buffs();
if (!debug) turn_right();
showview(0,0,0,0);
break;
case ';':debug=!debug;break;
case '<':nosides=!nosides;break;
case '=':nofloors=!nofloors;break;
case '>':drwsit=!drwsit;break;
}
}
while (c!=1);
}
void ask_video(void)
{
char c,ok,er;
printf("\nJaky videomode?:\n"
" 1) 640x480x256 Pomale pocitace\n"
" 2) 640x480xHiColor Pomale pocitace\n"
" 3) 640x480x256 Rychle pocitace\n"
" 4) 640x480xHiColor Rychle pocitace\n");
screen_buffer_size=640*480*2;
do
{
c=_bios_keybrd(_KEYBRD_READ)>>8;ok=1;er=0;
line480=1;
switch (c)
{
case 1:exit(0);
case 4:line480=1;er=initmode256(load_file("xlat256.pal"));
zooming=zooming2;ok=0;rot_phases=5;rot_step=70;
turn=turn2;
break;
case 5:line480=1;er=initmode32();
zooming=zooming1;ok=0;rot_phases=5;rot_step=70;
turn=turn1;
break;
case 2:line480=1;er=initmode256(load_file("xlat256.pal"));
zooming=zooming2;ok=0;zooming_step=2;
turn=turn2;
break;
case 3:line480=1;er=initmode32();
zooming=zooming1;ok=0;zooming_step=2;
turn=turn1;
break;
}
if (er)
{
ok=1;
if (er==-1)
printf("Rezim zrejme neni podporovan. Zkuste nainstalovat univbe\n");
else
printf("Graficka karta asi nepodporuje Linear Frame Buffer. \n"
"Pokud tomu tak neni, zkontrolujte zda neni vypnuty.\n");
}
}
while (ok);
memset(screen,0,screen_buffer_size);
buffer_2nd=(word *)getmem(screen_buffer_size);
memset(buffer_2nd,0,screen_buffer_size);
}
void main()
{
printf("%d\n",sizeof(showtabs));
p=load_file("konvert\\bredy.hi");
calc_points();
create_tables();
create_zooming();
ask_video();
put_picture(0,100,p);showview(0,0,0,0);free(p);
p2=load_file("konvert\\stena2.hi");
p=load_file("konvert\\stena2bl.hi");
strop=load_file("konvert\\strop1.hi");
podlaha=load_file("konvert\\podlaha1.hi");
sit=load_file("konvert\\sit.hi");
build_map();
render_scene(22,0);showview(0,0,0,0);
chozeni();
closemode();
}

380
libs/engine2.asm Normal file
View file

@ -0,0 +1,380 @@
.model small
.386
DGROUP group _DATA
tzoom struc
startptr DD ? ;0
texture DD ? ;4
textline DD ? ;8
linelen DD ? ;12
xtable DD ? ;16
ytable DD ? ;20
palette DD ? ;24
ycount DW ? ;28
xmax DW ?
tzoom ends
extrn _zoom:dword [8]
extrn _lbuffer:dword
extrn _screen:dword
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
public sikma_zleva_
sikma_zleva_:
mov edi,_zoom ;nacti ukazatel do obrazovky
mov ebx,_zoom[offset tzoom.palette] ;ukazatel na paletu
mov cx,word ptr _zoom[offset tzoom.ycount] ;velikost textury na y
shl ecx,16 ;vloz do horni pulky ecx
mov esi,_zoom[offset tzoom.texture] ;nacti ukazatel na texturu
skzl3: mov edx,_zoom[offset tzoom.xtable] ;nacti ukazetel na zvetsovaci tabulku x
push esi ;uchovej esi
push edi ;uchovej edi
mov cx,_zoom[offset tzoom.xmax]
skzl1: xor eax,eax ;vynuluj eax pro spravny vypocet
lodsb ;nacti bod
add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x
add edx,4 ;posun se v tabulce x o dalsi polozku
or al,al ;test bodu na nulu
jz skz1 ;preskoc transparetni barvu
cmp al,1 ;test bodu na jedna
jz skz2 ;ukonci kresleni linky pokud narazi na 1
mov ax,[eax*2+ebx] ;konverze barvy podle palety
mov [edi],ax ;nakresli bod na obrazovce
skz1: add edi,2 ;dalsi pozice
dec cx
jnz skzl1 ;opakuj dokola
skz2: pop edi ;obnov edi
pop esi ;obnov esi
mov edx,_zoom[offset tzoom.ytable] ;vyzvedni ukazatel na ytable
mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu
or cx,cx
jz skzskp
skzl2: add esi,_zoom[offset tzoom.textline] ;posun o jednu pozici
dec cx ;sniz citac
jnz skzl2 ;dokud neni nula
skzskp:add edx,2 ;dalsi hodnota v tabulce
mov _zoom[offset tzoom.ytable],edx ;uloaz na puvodni misto
sub edi,_zoom[offset tzoom.linelen] ;odecti tolik, kolik odpovida lince na obrazovce
sub ecx,10000h ;sniz horni pulku ecx o jedna
jnz skzl3 ;opakuj dokud neni nula
ret
public sikma_zprava_
sikma_zprava_:
mov edi,_zoom ;nacti ukazatel do obrazovky
mov ebx,_zoom[offset tzoom.palette] ;ukazatel na paletu
mov cx,word ptr _zoom[offset tzoom.ycount] ;velikost textury na y
shl ecx,16 ;vloz do horni pulky ecx
mov esi,_zoom[offset tzoom.texture] ;nacti ukazatel na texturu
skzp3: mov edx,_zoom[offset tzoom.xtable] ;nacti ukazetel na zvetsovaci tabulku x
push esi ;uchovej esi
push edi ;uchovej edi
mov cx,_zoom[offset tzoom.xmax]
skzp1: xor eax,eax ;vynuluj eax pro spravny vypocet
lodsb ;nacti bod
add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x
add edx,4 ;posun se v tabulce x o dalsi polozku
or al,al ;test bodu na nulu
jz skz3 ;preskoc transparetni barvu
cmp al,1 ;test bodu na jedna
jz skz4 ;ukonci kresleni linky pokud narazi na 1
mov ax,[eax*2+ebx] ;konverze barvy podle palety
mov [edi],ax ;nakresli bod na obrazovce
skz3: sub edi,2 ;dalsi pozice
dec cx
jnz skzp1 ;opakuj dokola
skz4: pop edi ;obnov edi
pop esi ;obnov esi
mov edx,_zoom[offset tzoom.ytable] ;vyzvedni ukazatel na ytable
mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu
or cx,cx
jz skpskp
skzp2: add esi,_zoom[offset tzoom.textline] ;posun o jednu pozici
dec cx ;sniz citac
jnz skzp2 ;dokud neni nula
skpskp: add edx,2 ;dalsi hodnota v tabulce
mov _zoom[offset tzoom.ytable],edx ;uloaz na puvodni misto
sub edi,_zoom[offset tzoom.linelen] ;odecti tolik, kolik odpovida lince na obrazovce
sub ecx,10000h ;sniz horni pulku ecx o jedna
jnz skzp3 ;opakuj dokud neni nula
ret
public zooming32_
zooming32_:
;esi - zdrojovy blok
;edi - cil
;zoom.xtable - tabulka pro x
;zoom.xtable - tabulka pro y
;zoom.textline - rozdil mezi pravym okrajem a levym okrajem
; pri prechodu na novou radku
;ecx ysize:xsize
push ebp
mov bp,cx
mov ebx,_zoom[offset tzoom.ytable]
z32d: mov cx,bp
mov edx,_zoom[offset tzoom.xtable]
push esi
z32c: mov al,[edx]
inc edx
or al,al
jz z32a
lodsw
stosw
stosw
jmp z32b
z32a: movsd
z32b: dec cx
jnz z32c
pop esi
mov eax,[ebx]
and eax,0ffffh
add esi,eax
add ebx,2
add edi,_zoom[offset tzoom.textline]
xor cx,cx
sub ecx,10000h
jnz z32d
pop ebp
ret
public zooming_lo_
zooming_lo_:
;esi - zdrojovy blok
;edi - cil
;zoom.xtable - tabulka pro x
;zoom.xtable - tabulka pro y
;zoom.textline - rozdil mezi pravym okrajem a levym okrajem
; pri prechodu na novou radku
;ecx ysize:xsize
;ebx xlat
push ebp
mov bp,cx
zlod: mov cx,bp
mov edx,_zoom[offset tzoom.xtable]
push esi
zloc: xor eax,eax
mov al,[edx]
inc edx
or al,al
jz zloa
lodsw
mov eax,[ebx+eax*2]
stosb
jmp zlob
zloa: lodsw
mov eax,[ebx+eax*2]
stosb
add esi,2
zlob: dec cx
jnz zloc
pop esi
mov edx,_zoom[offset tzoom.ytable]
mov eax,[edx]
shl eax,1
and eax,0ffffh
add esi,eax
add edx,2
mov _zoom[offset tzoom.ytable],edx
add edi,_zoom[offset tzoom.textline]
xor cx,cx
sub ecx,20000h
jnz zlod
pop ebp
ret
public zooming256_
zooming256_:
;esi - zdrojovy blok
;edi - cil
;zoom.xtable - tabulka pro x
;zoom.xtable - tabulka pro y
;zoom.textline - rozdil mezi pravym okrajem a levym okrajem
; pri prechodu na novou radku
;ecx ysize:xsize
;ebx xlat
push ebp
mov bp,cx
z256d: mov cx,bp
mov edx,_zoom[offset tzoom.xtable]
push esi
z256c: xor eax,eax
mov al,[edx]
inc edx
or al,al
jz z256a
lodsw
mov eax,[ebx+eax*2]
stosb
stosb
jmp z256b
z256a: lodsw
mov eax,[ebx+eax*2]
stosb
xor eax,eax
lodsw
mov eax,[ebx+eax*2]
stosb
z256b: dec cx
jnz z256c
pop esi
mov edx,_zoom[offset tzoom.ytable]
mov eax,[edx]
and eax,0ffffh
add esi,eax
add edx,2
mov _zoom[offset tzoom.ytable],edx
add edi,_zoom[offset tzoom.textline]
xor cx,cx
sub ecx,10000h
jnz z256d
pop ebp
ret
; public scroll_left_
;scroll_left_: ;edi - kam
; ;lbuffer - obrazovka
; ;zoom.startptr - novy obsah obrazovky
; ;ebx - xlat
; ;eax - o_kolik
; mov bx,ax ;horni pulka ebx vi o kolik se posunuje vlevo
; rol ebx,16
; mov edx,640 ;dolni pulka ebx vi, jak velky blok je presouvan
; sub edx,eax
; sub edx,2
; mov bx,dx
; mov esi,edi ;vypocet esi
; shl eax,1 ;esi = edi + 2 * o_kolik;
; add esi,eax
; mov edx,360 ;napln citac edx cislem udavajici pocet radku
; add edi,_lbuffer ;k edi na zacatku pricti hodnotu _lbuffer
; mov eax,esi ;uchovej esi v eax, behem prenosu bude modifikovan
;scrl1: add esi,_lbuffer ;pricti k esi zacatek obrazovky
; xor ecx,ecx ;vynuluj ecx
; mov cx,bx ;do ecx naladuj delku bloku
; shr ecx,1 ;presun 32-bit
; rep movsd
; adc ecx,1
;; rep movsw
; mov esi,_zoom ;vem ukazatel na novy obsah
; mov ecx,ebx ;vezmi horni pulku EBx
; shr ecx,16 ;to je hodnota, kolik se ma v prava doplnit
; shr ecx,1 ;presun 32-bit
; rep movsd
; adc ecx,1
; rep movsw
; add _zoom,640*2 ;dalsi radka
;; add eax,640*2 ;dalsi radka
; mov esi,eax
; dec edx ;dokud neni konec
; jnz scrl1
; ret
;
public scroll_support_32_
scroll_support_32_:
;edi - lbuffer + pozice na obrazovce
;esi - oldbuffer
;edx - newbuffer
;ebx - xlat
;ecx - size;
push ebp ;uchovej ebp
mov ebp,360 ;ebp pro tuto chvili predstavuje citac
mov eax,ecx ;uchovej ecx jeste v eac - zachova citac sloupcu
scrl1: push esi ;uchovej esi
shr ecx,1 ;presun ecx bloku
rep movsd
rcl ecx,1
rep movsw
mov ecx,640 ;dopocitej ecx do 640
sub ecx,eax
pop esi ;obnov esi
xchg esi,edx ;esi je nyni novy blok
push esi ;uchovek esi
shr ecx,1 ;presun
rep movsd
rcl ecx,1
rep movsw
pop esi ;obnov esi
xchg esi,edx ;vrat edx a esi do puvodniho stavu
mov ecx,eax ;obnov zase ecx z eax
add esi,1280 ;dalsi radek
add edx,1280
dec ebp ; dokud nejsme na konci
jnz scrl1 ;opakuj
pop ebp
ret
public scroll_support_256_
scroll_support_256_:
;edi - lbuffer + pozice na obrazovce
;esi - oldbuffer
;edx - newbuffer
;ebx - xlat
;ecx - size;
push ebp ;uchovej ebp
mov ebp,360 ;ebp pro tuto chvili predstavuje citac
scrl1a: push ecx ;uchovej ecx jeste v eac - zachova citac sloupcu
push esi ;uchovej esi
xor eax,eax
scrl2a: lodsw
mov al,[ebx+2*eax]
xor ebx,1
stosb
dec ecx
jnz scrl2a
pop esi
xchg esi,edx ;esi je nyni novy blok
pop eax
mov ecx,640 ;dopocitej ecx do 640
sub ecx,eax
push eax
push esi ;uchovek esi
xor eax,eax
scrl3a: lodsw
mov al,[ebx+2*eax]
xor ebx,1
stosb
dec ecx
jnz scrl3a
pop esi ;obnov esi
xchg esi,edx ;vrat edx a esi do puvodniho stavu
pop ecx ;obnov zase ecx z eax
add esi,1280 ;dalsi radek
add edx,1280
xor ebx,1
dec ebp ; dokud nejsme na konci
jnz scrl1a ;opakuj
pop ebp
ret
public fcdraw_ ;Kresli strop nebo podlahu podle draw_table
;EDX - sourceTxt
;EBX - TargerTxt - LineOfset
; (Lineofs je pocet bajtu odpovidajici
; souradnicim [0,184] pro podlahu nebo [0,0]
; pro strop)
;EAX - draw_table
fcdraw_:mov esi,[eax]
mov edi,esi
add edi,ebx
add esi,edx
mov ecx,[eax+4]
shr ecx,1
rep movsd
rcl ecx,1
rep movsw
mov ecx,[eax+8]
add eax,12
or ecx,ecx
jnz fcdraw_
ret
_TEXT ends
END

23
libs/errtest.c Normal file
View file

@ -0,0 +1,23 @@
#include <dos.h>
#include <bios.h>
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include "doserr.h"
void *err_stack;
char err_proc(int error,char disk,char info)
{
cprintf("Device error %04X %c %03X \n\r",error,disk+'@',info);
return 3;
}
main()
{
FILE *f;
err_stack=malloc(16384);
install_dos_error(err_proc,(char *)err_stack+16384);
f=fopen("a:\test","r");
}

629
libs/event.c Normal file
View file

@ -0,0 +1,629 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "event.h"
#include "devices.h"
#include <mem.h>
//#include <dpmi.h>
#include <malloc.h>
#include <bios.h>
//#include <i86.h>
#include <time.h>
#include "memman.h"
#include <setjmp.h>
#include <signal.h>
#include <assert.h>
static jmp_buf jmpenv;
#define find_event_msg(where,what,res) \
{\
res=(where);\
while (res!=NULL && res->event_msg!=(what)) res=res->next;\
}
#define find_event_proc(where,what,res) \
{\
res=(where);\
while (res!=NULL && res->proc!=(what)) res=res->next;\
}
#define find_event_msg_proc(where,xmsg,xproc,res) \
{\
T_EVENT_ROOT *pt; \
find_event_msg(where,xmsg,pt);\
if (pt) find_event_proc(pt->list,xproc,res) else res=NULL;\
}
char exit_wait=0;
T_EVENT_ROOT *ev_tree=NULL;
char freeze_on_exit=0;
long ev_buff_msg[EVENT_BUFF_SIZE]={0};
void *ev_buff_dta[EVENT_BUFF_SIZE]={NULL};
int ev_poz=0;
char *otevri_zavoru;
void **tasklist_sp;
void **tasklist_low;
void **tasklist_top;
int *tasklist_events;
char *task_info;
int taskcount=0;
int foretask=0;
int nexttask=0;
long taskparam;
long err_last_stack;
void *err_to_go;
T_EVENT_ROOT *add_event_message(T_EVENT_ROOT **tree,int msg)
{
T_EVENT_ROOT *r,*r1;
if (*tree==NULL)
{
*tree=getmem(sizeof(T_EVENT_ROOT));
r=*tree;
r->next=NULL;
}
else
{
r=getmem(sizeof(T_EVENT_ROOT));
r1=*tree;
while (r1->next!=NULL) r1=r1->next;
r->next=NULL;
r1->next=r;
}
r->event_msg=msg;
//r->used=0;
r->list=NULL;
return r;
}
T_EVENT_POINT *add_event(T_EVENT_ROOT **tree,int msg,EV_PROC proc,char end)
{
T_EVENT_ROOT *r;
T_EVENT_POINT *p;
find_event_msg(*tree,msg,r);
if (r==NULL)
{
r=add_event_message(tree,msg);
p=r->list=New(T_EVENT_POINT);
p->next=NULL;
}
else if (end && r->list!=NULL)
{
T_EVENT_POINT *q=r->list;
p=getmem(sizeof(T_EVENT_POINT));
while (q->next!=NULL) q=q->next;
p->next=NULL;
q->next=p;
}
else
{
p=getmem(sizeof(T_EVENT_POINT));
p->next=r->list;
r->list=p;
}
p->proc=proc;
p->nezavora=1;
p->nezavirat=0;
p->user_data=NULL;
p->calls=0;
return p;
}
void delete_event_msg(T_EVENT_ROOT **tree,int msg)
{
T_EVENT_ROOT *r;
r=*tree;
if (r==NULL) return;
if (r->event_msg==msg)
{
if (r->used) return;
*tree=r->next;
free(r);
}
else
{
T_EVENT_ROOT *p;
while ((p=r->next)!=NULL && p->event_msg!=msg) r=p;
if (p!=NULL)
{
if (p->used) return;
r->next=p->next;
free(p);
}
}
}
void delete_event(T_EVENT_ROOT **tree,int msg,EV_PROC proc)
{
T_EVENT_ROOT *r;
T_EVENT_POINT *p;
find_event_msg(*tree,msg,r);
if (r==NULL) return;
p=r->list;
if (p->proc==proc)
{
r->list=p->next;
free(p);
}
else
{
T_EVENT_POINT *q;
while ((q=p->next)!=NULL && q->proc!=proc) p=q;
if (q!=NULL)
{
p->next=q->next;
free(q);
}
}
if (r->list==NULL) delete_event_msg(tree,msg);
}
void force_delete_curr (T_EVENT_ROOT **tree,T_EVENT_ROOT *r, T_EVENT_POINT *p)
{
T_EVENT_POINT *q;
q=r->list;
if (q==p)
{
r->list=p->next;
free(p);
tree;
if (r->list==NULL) delete_event_msg(tree,r->event_msg);
}
else
{
while (q->next!=p) q=q->next;
q->next=p->next;
free(p);
}
}
/*
static void unsuspend_task(EVENT_MSG *msg)
{
int i;
int nt;
nt=nexttask;
for(i=1;i<taskcount;i++) if (tasklist_sp[i]!=NULL && task_info[i] & TASK_EVENT_WAITING && tasklist_events[i]==msg->msg)
{
nexttask=i;
task_info[nexttask]&=~TASK_EVENT_WAITING;
task_sleep(msg->data);
}
nexttask=nt;
}
*/
void enter_event(T_EVENT_ROOT **tree,EVENT_MSG *msg)
{
T_EVENT_ROOT *r;
T_EVENT_POINT *p,*s;
int ev=msg->msg;
find_event_msg(*tree,msg->msg,r);
if (r!=NULL)
{
r->used++;
s=r->list;
for(p=r->list;p!=NULL;)
{
s=p->next;
if (p->proc!=NULL && p->nezavora)
{
T_EVENT_POINT *z=p;
if (p->proc==PROC_GROUP) z=(T_EVENT_POINT *)p->user_data;
p->nezavora=p->nezavirat;
otevri_zavoru=&p->nezavora;
p->calls++;
z->proc(msg,&(z->user_data));
p->calls--;
p->nezavora=1;
if (msg->msg==-2)
{
p->proc=NULL;
msg->msg=ev;
}
s=p->next;
if (!p->calls && p->proc==NULL)
force_delete_curr(tree,r,p);
if (msg->msg==-1) break;
}
/* if (p->next!=s)
if (r->list!=p)
{
for(q=r->list;q!=NULL;q=q->next)
if (q->next==p)
{
s=p->next;
break;
}
else if (q->next==s) break;
break;
}
else
s=p->next;*/
p=s;
}
r->used--;
/* for(p=r->list;p!=NULL;)
{
s=p->next;
if (p->proc==NULL)
force_delete_curr(tree,r,p);
p=s;
}*/
}
unsuspend_task(msg);
}
T_EVENT_POINT *install_event(T_EVENT_ROOT **tree,long ev_num,EV_PROC proc,void *procdata,char end)
//instaluje novou udalost;
{
EVENT_MSG x;
void **user=NULL;
T_EVENT_POINT *p;
x.msg=E_INIT;
x.data=procdata;
proc(&x,&user);
if (x.data!=NULL)
{
p=add_event(tree,ev_num,proc,end);
p->user_data=user;
}
return p;
}
void deinstall_event(T_EVENT_ROOT **tree,long ev_num,EV_PROC proc,void *procdata)
//deinstaluje udalost;
{
EVENT_MSG x;
T_EVENT_ROOT *r;
T_EVENT_POINT *p;
find_event_msg(*tree,ev_num,r);
if (r==NULL) return;
find_event_proc(r->list,proc,p);
if (p==NULL) return;
x.msg=E_DONE;
x.data=procdata;
proc(&x,&p->user_data);
if (p->user_data!=NULL) free(p->user_data);
p->proc=NULL;
p->user_data=NULL;
if (!p->calls) force_delete_curr(tree,r,p);
}
void tree_basics(T_EVENT_ROOT **ev_tree,EVENT_MSG *msg)
{
char *p;
void *(*q)();
EVENT_MSG tg;
if (msg->msg==E_ADD || msg->msg==E_ADDEND)
{
T_EVENT_POINT *r;
shift_msg(msg,tg);
p=(char *)(tg.data);
p+=4;
find_event_msg_proc(*ev_tree,tg.msg,tg.data,r);
assert(r==NULL);
if (r==NULL)
install_event(ev_tree,tg.msg,*(EV_PROC *)tg.data,p,msg->msg==E_ADDEND);
return;
}
if (msg->msg==E_INIT)
{
memcpy(&q,msg->data,4);
q();
return;
}
if (msg->msg==E_DONE)
{
shift_msg(msg,tg);
p=(char *)(tg.data);
p+=4;
deinstall_event(ev_tree,tg.msg,*(EV_PROC *) tg.data,p);
return;
}
if (msg->msg==E_GROUP)
{
int pocet,i,addev;
T_EVENT_POINT *pp;
EVENT_MSG *tgm=&tg;
long *p;void *proc;
shift_msg(msg,tg);addev=tg.msg; if (addev!=E_ADD || addev!=E_ADDEND) return;
shift_msg(tgm,tg);
pocet=tg.msg;
p=tg.data;proc=p+pocet*sizeof(long);
for(i=0;i<pocet;i++,p++) if (i!=0)
{
T_EVENT_POINT *q;
q=add_event(ev_tree,*p,proc,addev==E_ADDEND);
q->user_data=(void *)pp;
q->proc=PROC_GROUP;
}
else
pp=install_event(ev_tree,*p,proc,((long *)proc+1),addev==E_ADDEND);
}
}
void send_message(long message,...)
{
long *p;
EVENT_MSG x;
p=&message;
x.msg=*p++;
x.data=(void *)p;
if (x.msg==E_ADD || x.msg==E_INIT || x.msg==E_DONE) tree_basics(&ev_tree,&x);
else
enter_event(&ev_tree,&x);
}
void timer(EVENT_MSG *msg)
{
static unsigned long lasttime=0;
if (msg->msg==E_WATCH)
{
unsigned long tm=GetTickCount()/TIMERSPEED;
if (tm==lasttime) return;
lasttime=tm;
send_message(E_TIMER,tm);
return;
}
}
void tasker(EVENT_MSG *msg,void **data)
{
data;
switch (msg->msg)
{
case E_INIT:
/* tasklist_sp=New(void *);
tasklist_low=New(void *);
tasklist_top=New(void *);
task_info=New(char);
taskcount=1;
memset(task_info,0,taskcount);*/
break;
case E_WATCH:
case E_IDLE:
default:
if (q_any_task()>=1)
task_sleep(NULL);
break;
case E_DONE:
{
int i;
memset(task_info,1,taskcount);
do
{
for (i=1;i<taskcount;i++)
if (tasklist_sp[i]!=NULL) break;
if (i!=taskcount) task_sleep(NULL);
}
while (i<taskcount);
free(tasklist_sp);
free(tasklist_low);
free(task_info);
}
break;
}
}
/*void except_free_stack(void *ptr);
#pragma aux except_free_stack parm [eax]=\
"mov esp,eax"\
"sub esp,10h"\
"popf"\
"pop ax"\
"mov ebp,esp"\
"lss esp,[ebp]"\
"mov ebp,esp"
void except_GPF()
#pragma aux except_GPF parm[]
{
raise_error(ERR_MEMREF);
}
*/
void init_events()
{
send_message(E_ADD,E_WATCH,keyboard);
send_message(E_ADD,E_WATCH,timer);
send_message(E_ADD,E_WATCH,tasker);
#ifdef nodebug
alloc_exception(0xD,except_GPF);
alloc_exception(0xE,except_GPF);
#endif
}
static char do_events_called=0;
void do_events()
{
do_events_called=1;
if (!q_is_mastertask()) task_sleep(NULL);
else
{
send_message(E_WATCH);
send_message(E_IDLE);
}
}
void error_show(int error_number)
{
send_message(E_PRGERROR,&error_number);
if (!error_number) abort();
}
void escape()
{
exit_wait=0;
do
{
send_message(E_WATCH);
send_message(E_IDLE);
if (do_events_called==0) ShareCPU();
else do_events_called=0;
}
while (!exit_wait);
exit_wait=0;
}
T_EVENT_ROOT *gate_basics(EVENT_MSG *msg, void **user_data)
{
T_EVENT_ROOT *p;
EVENT_MSG msg2;
memcpy(&p,user_data,4);
shift_msg(msg,msg2);;
if (msg2.msg==E_ADD || msg2.msg==E_INIT || msg2.msg==E_DONE)
tree_basics((T_EVENT_ROOT **)user_data,&msg2);
return p;
}
/*
int create_task()
{
int i;
for(i=1;i<taskcount;i++)
if (tasklist_sp[i]==NULL) break;
if (i>=taskcount)
{
taskcount++;
tasklist_sp=grealloc(tasklist_sp,taskcount*4);
tasklist_low=grealloc(tasklist_low,taskcount*4);
tasklist_top=grealloc(tasklist_top,taskcount*4);
task_info=grealloc(task_info,taskcount);
tasklist_events=grealloc(tasklist_events,taskcount*sizeof(int));
}
return i;
}
*/
void task_terminating();
/*
long getflags();
#pragma aux getflags = \
"pushfd"\
"pop eax"\
;*/
/*
int add_task(int stack,void *name,...)
{
int task,i;
long *sp,*spp;
task=create_task();
if (task==-1)
{
send_message(E_MEMERROR);
return -1;
}
sp=malloc(stack);
if (sp==NULL)
{
send_message(E_MEMERROR);
return -1;
}
spp=(long *)((char *)sp+stack-17*4);
memset(sp,0,stack);
memcpy(spp,&name,17*4);
*spp=(long )task_terminating;
spp--;*spp=(long)name;
for(i=0;i<9;i++)
{
spp--;
*spp=0;
if (i==5) *spp=(long)((char *)sp+stack);
}
tasklist_low[task]=(void *)sp;
tasklist_top[task]=(void *)((char *)sp+stack);
tasklist_sp[task]=(void *)spp;
task_info[task]=TASK_RUNNING;
return task;
}
void term_task(int id_num)
{
task_info[id_num]=TASK_TERMINATING;
return;
}
char is_running(int id_num)
{
return tasklist_sp[id_num]!=NULL;
}
static void suspend_task(int id_num,int msg)
{
task_info[id_num]|=TASK_EVENT_WAITING;
tasklist_events[id_num]=msg;
}
void shut_down_task(int id_num)
{
free(tasklist_low[id_num]);
tasklist_sp[id_num]=0;
if (nexttask==id_num) nexttask=0;
}
*/
/*void raise_error(int error_number)
{
longjmp(jmpenv,error_number);
}
*/
/*static void unsuspend_task_by_event(EVENT_MSG *msg,int **idnum)
{
if (msg->msg==E_INIT)
{
*idnum=New(int);
**idnum=*(int *)msg->data;
}
else
{
int nt=nexttask;
nexttask=**idnum;
free(*idnum);
*idnum=NULL;
task_info[nexttask]&=~TASK_EVENT_WAITING;
task_sleep(msg->data);
msg->msg=-2;
nexttask=nt;
}
}
*/
/*void *task_wait_event(long event_number)
{
if (!curtask) return NULL;
suspend_task(curtask,event_number);
return task_sleep(NULL);
}
*/

157
libs/event.h Normal file
View file

@ -0,0 +1,157 @@
#ifndef __EVENT_H
#define __EVENT_H
//#define nodebug // 0 znamena ze se nealokuje udalost pro chybu
// Tato knihovna definuje zakladni systemove konstanty
// pro system hlaseni a udalosti
// zakladni
#define E_INIT 1 //inicializace udalost (interni)
#define E_ADD 2 //pridani udalosti do stromu
#define E_DONE 3 //odebrani udalosti ze stromu
#define E_IDLE 4 //udalost volana v dobe necinnosti
#define E_GROUP 5 //vytvareni skupin udalosti
#define E_ADDEND 7 //pridani udalosti do stromu na konec.
#define E_MEMERROR 8 //udalost je vyvolana pri nedostatku pameti
// neni prirazena ZADNA standardni akce!!!
#define E_WATCH 6 //udalost majici prednost pred idle
//slouzi pro procedury sledujici cinnost hardware
#define E_PRGERROR 9 //udalost vyvolana pri chybe programu
//parametrem udalosti je ukazatel na int ktery oznamuje cislo chyb
//vysledek zapsat do tohoto intu (0-exit,1-ignorovat)
#define E_ADD_REPEAT 10 //pridani udalosti do stromu
#define ERR_MEMREF -1
#define ERR_ILLEGI -2
// zarizeni
#define E_KEYBOARD 10
#define E_MOUSE 11
#define E_TIMER 12
#define TASK_RUNNING 0
#define TASK_TERMINATING 1
#define TASK_EVENT_WAITING 2
#define shift_msg(msgg,tg) ((tg.msg=*(long *)msgg->data),(tg.data=(void *)((long *)msgg->data+1)))
#define EVENT_BUFF_SIZE 16
typedef void (*EV_PROC)(void *,void *) ;
#define PROC_GROUP (EV_PROC )1
//typedef struct event_list
// {
// long *table; //tabulka udalosti
// EV_PROC *procs; //co se ma pri danne udalosti stat
// void *(*user_data); //ukazatel na uzivatelska data
// char *zavora; //1 znamena ze udalost je povolena
// long max_events; // maximalni pocet udalosti, na ktere je system rezervova
// long count; //aktualni pocet udalosti
// }EVENT_LIST;
/* event procedura ma dva parametry
1. je ukazatel na tzv. message, tato struktura je videt dole.
Predava se cislo udalosti, ktera nastala a ukazatel na dalsi udaje
tykajici se udalosti
2. je ukazatel na ukazatel. Tyto 4 bajty jsou volnym mistem pro samotnou
udalost. Pri instalaci ma obsah NULL. Udalost si muze volne alokovat
pamet a pouzit ji pro svoji porebu. Pri deinstalaci se nestara o jeji
dealokaci, o to se postara system
(ukazatel na user_data)
*/
typedef struct t_event_point
{
EV_PROC proc;
void *user_data;
char nezavora;
char nezavirat;
int calls;
struct t_event_point *next;
}T_EVENT_POINT;
typedef struct t_event_root
{
int event_msg;
int used;
struct t_event_root *next;
T_EVENT_POINT *list;
}T_EVENT_ROOT;
typedef struct event_msg
{
long msg;
void *data;
}EVENT_MSG;
extern char exit_wait; // 1 - opousti aktivni cekaci event;
extern char freeze_on_exit; //1 - po opusteni udalosti cela cesta uzamcena
extern char *otevri_zavoru;
//extern int curtask;
//extern char *task_info;
void init_events();
// inicalizuje zakladni strom udalosto
void send_message(long message,...);
// posila zpravu do stromu
void tree_basics(T_EVENT_ROOT **ev_tree,EVENT_MSG *msg);
// pripojuje zakladni funkce brany, jako je instalace listu a jejich deinstalace
T_EVENT_ROOT *gate_basics(EVENT_MSG *msg, void *user_data);
// implementace brany
/* vstupuji informace, jake dostane brana pri zavolani
vystupuji informace s jakymi musi vstoupit do stromu.
Je li MSG = NULL byla zavolana udalost E_DESTROY a brana se musi zlikvidovat
vysledkem funkce je ukazatel na koren stromu brany.
*/
void enter_event(T_EVENT_ROOT **tree,EVENT_MSG *msg);
//vstupuje do stromu s udalosti (msg)
void do_events();
void escape();
#include <FCS_Tasker.h>
/*
void *task_sleep(void *param);
//#pragma aux task_sleep parm [eax] value [eax]
int add_task(int stack,void *name,...);
//spusti provadeni funkce v rizenem multitaskingu (switch task)
void term_task(int id_num);
//informuje task o ukonceni. Uloha by mela zkoncit
void shut_down_task(int id_num);
//Nasilne ukonci ulohu
void raise_error(int error_number);
EVENT_MSG *task_wait_event(long event_number);
char is_running(int id_num);
*/
void timer(EVENT_MSG *msg);
#define EVENT_PROC(name) void name(EVENT_MSG *msg,void **user_ptr)
#define WHEN_MSG(msg_num) if (msg->msg==msg_num)
#define UNTIL_MSG(msg_num) if (msg->msg!=msg_num)
#define GET_DATA(data_type) (*(data_type *)msg->data)
#define GET_DATA_PTR(data_type) ((data_type *)msg->data);
#define GET_USER(data_type) (*(data_type *)user_ptr)
#define SAVE_USER_PTR(p) (*user_ptr=p)
#define GET_USER_PTR() user_ptr
#define EVENT_RETURN(value) msg->msg=value
#define GET_MSG_VAR() msg
#define GET_MSG() msg->msg
#define TASK_GET_TERMINATE() ((task_info[cur_task] & TASK_TERMINATING)!=0)
#define EVENT_HALT -1
#define EVENT_DONE -2
#define EVENT_HALT_DONE -3
#endif

31
libs/expand.c Normal file
View file

@ -0,0 +1,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include "memman.h"
void help()
{
puts("Usage: Extract skeldal.ddl source.ext target.ext");
exit(1);
}
main(int argc,char **argv)
{
void *z;long s;
FILE *f;
if (argc!=4) help();
OPEN_LOG("");
init_manager(argv[1],NULL);
z=afile(argv[2],read_group(0),&s);
if (z==NULL)
{
puts("File not found");
return 1;
}
f=fopen(argv[3],"w");
fwrite(z,1,s,f);
fclose(f);
puts("File successfuly expanded");
return 0;
}

32
libs/extract.c Normal file
View file

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "memman.h"
void help()
{
puts("Extract: Usage: Extract file.ddl source.ext target.ext");
exit(1);;
}
main(int argc,char **argv)
{
void *z;long s;
FILE *f;
if (argc==3) help();
init_manager(argv[1],NULL);
z=afile(strupr(argv[2]),read_group(0),&s);
if (z==NULL)
{
puts("File not found");
close_manager();
return 1;
}
f=fopen(argv[3],"wb");
fwrite(z,1,s,f);
fclose(f);
puts("File successfuly expanded");
close_manager();
return 0;
}

29
libs/fastload.c Normal file
View file

@ -0,0 +1,29 @@
#include <stdio.h>
#include <event.h>
#define LOAD_BUFFER 4096
int _fast_load(char *ptr,long size,FILE *f)
{
if (size>LOAD_BUFFER) size=4096;
return fread(ptr,1,size,f);
}
size_t fread(void *ptr,size_t i,size_t j,FILE *f)
{
long s,z,celk=0;
char *c;
c=ptr;
s=i*j;
do
{
z=_fast_load(c,s,f);
s-=z;
c+=z;
celk+=z;
do_events();
}
while(s || !z);
return z;
}

118
libs/graphtst.c Normal file
View file

@ -0,0 +1,118 @@
#include "types.h"
#include <stdio.h>
#include <i86.h>
#include <malloc.h>
#include "devices.h"
#include "event.h"
#include "bgraph.h"
#include "bmouse.h"
#include "memman.h"
#define E_TEST 200
void gettest()
{
register_ms_cursor(load_file("sipka.HI"));
show_ms_cursor(0,0);
// install_mouse_handler();
hranice_mysky(0,0,639,399);
while (!(ms_basic_info.mouse_code & 0xfffe))
{
if (ms_basic_info.mouse_event)
move_ms_cursor(ms_basic_info.mouse_cx,ms_basic_info.mouse_dx);
}
}
void modetest()
{
word y;
curcolor=0x7fff;
for(y=0;y<400;y+=10)
{
line(639-y,399,639,y);
line(639-y,0,639,399-y);
line(y,0,0,399-y);
line(y,399,0,y);
}
curcolor=0x6318;
bar32(160,100,480,300);
curcolor=0x7fff;
hor_line32(160,100,480);
hor_line32(161,101,479);
ver_line32(160,101,300);
ver_line32(161,102,299);
curcolor=0x4210;
hor_line32(160,300,480);
hor_line32(161,299,479);
ver_line32(480,100,300);
ver_line32(479,101,299);
fontdsize=0;
position(165,105);outtext("TEXT");
}
void pic_test(word x,word y,char *filename)
{
void *p;
p=load_file(filename);
if (p==NULL) return;
put_picture(x,y,p);
free(p);
}
void main_x()
{
if ((palmem=load_file("xlat256.pal"))==NULL) return;
// initmode_lo (palmem);
initmode32();
curfont=load_file("d:\\tp\\vga\\boldcz.fon");
if (curfont==NULL) return;
pic_test(0,0,"ADD11.HI");
showview(0,0,0,0);getchar();
modetest();
showview(0,0,0,0);
}
void *test1(EVENT_MSG *a,void *b)
{
MS_EVENT *ms;
b;
if (a->msg==E_INIT) return &test1;
ms=get_mouse(a);
exit_wait=ms->tl1;
return NULL;
}
void *test2(EVENT_MSG *a,void *b)
{
b;
if (a->msg==E_INIT) return &test2;
exit_wait=1;
return NULL;
}
void main()
{
init_events(20);
main_x();
init_mysky();
register_ms_cursor(load_file("sipka.HI"));
ukaz_mysku();
send_message(E_ADD,E_MOUSE,&test1);
send_message(E_ADD,E_KEYBOARD,&test2);
escape();
send_message(E_DONE,E_MOUSE,&test1);
send_message(E_DONE,E_KEYBOARD,&test2);
closemode();
// deinstall_mouse_handler();
}

932
libs/gui.c Normal file
View file

@ -0,0 +1,932 @@
#include <skeldal_win.h>
//Gui system - object system + graphic
#include "types.h"
#include <stdio.h>
#include <mem.h>
#include <malloc.h>
#include "memman.h"
#include "event.h"
#include "devices.h"
#include "bmouse.h"
#include "bgraph.h"
#include "gui.h"
#define E_REDRAW_DESKTOP 2010
#define E_REDRAW_WINDOW 2000
void *gui_background=NULL;
extern T_EVENT_ROOT *ev_tree;
WINDOW *desktop={NULL},*waktual={NULL};;
OBJREC *o_aktual={NULL},*o_end={NULL},*o_start={NULL};
CTL3D noneborder={0,0,0,0};
FC_TABLE f_default;
word desktop_y_size;
char force_redraw_desktop=0;
static char change_flag=0,f_cancel_event=0;
word *default_font;
void empty()
{
}
void empty1(OBJREC *o)
{
o;
}
void empty3(EVENT_MSG *ms,OBJREC *o)
{
o;ms;
}
void empty2(int x1,int y1,int x2,int y2,OBJREC *o)
{
o;x1;y1;x2;y2;
}
void draw_border(integer x,integer y,integer xs,integer ys,CTL3D *btype)
{
word i,j,c;
c=curcolor;
j=btype->ctldef;
for (i=0;i<btype->bsize;i++)
{
x--;y--;xs+=2;ys+=2;
if (j & 1) curcolor=btype->shadow; else curcolor=btype->light;
hor_line(x,y,xs+x);
ver_line(x,y,ys+y);
if (j & 1) curcolor=btype->light; else curcolor=btype->shadow;
hor_line(x,y+ys,xs+x);
ver_line(x+xs,y,ys+y);
j>>=1;
}
curcolor=c;
}
void check_window(WINDOW *w)
{
if (w->x<=w->border3d.bsize) w->x=w->border3d.bsize;
if (w->y<=w->border3d.bsize) w->y=w->border3d.bsize;
if (w->x>=SCR_WIDTH_X-w->border3d.bsize-w->xs) w->x=SCR_WIDTH_X-w->border3d.bsize-w->xs-1;
if (w->y>=desktop_y_size-w->border3d.bsize-w->ys) w->y=desktop_y_size-w->border3d.bsize-w->ys-1;
}
void show_window(WINDOW *w)
{
int ok;
ok=w->border3d.bsize;
showview(w->x-ok,w->y-ok,w->xs+(ok<<1),w->ys+(ok<<1));
}
void draw_cl_window(WINDOW *o)
{
curcolor=o->color;
bar32(o->x,o->y,o->x+o->xs,o->y+o->ys);
draw_border(o->x,o->y,o->xs,o->ys,&o->border3d);
}
WINDOW *create_window(int x,int y, int xs, int ys, word color, CTL3D *okraj)
{
WINDOW *p;
p=(WINDOW *)getmem(sizeof(WINDOW));
p->x=x;p->y=y;p->xs=xs;p->ys=ys;
p->color=color;memcpy(&(p->border3d),okraj,sizeof(CTL3D));
p->objects=NULL;
p->modal=0;
p->popup=0;
p->minimized=0;
p->window_name=NULL;
p->minsizx=MINSIZX;
p->minsizy=MINSIZY;
p->idlist=NULL;
p->draw_event=draw_cl_window;
check_window(p);
return p;
}
int send_lost()
{
EVENT_MSG msg;
msg.msg=E_LOST_FOCUS;
if (o_aktual!=NULL)
{
o_aktual->events[2]();
if (f_cancel_event) return -1;
o_aktual->runs[2](&msg,o_aktual);
o_aktual=NULL;
}
return 0;
}
void select_window(long id)
{
WINDOW *p,*q;
if (waktual->id==id) return;
if (waktual->modal) return;
if (send_lost()) return;
p=desktop;
while (p!=NULL && p->id!=id) p=p->next;
if (p==NULL) return;
q=desktop;
if (p!=desktop)
{
while (q->next!=p) q=q->next;
q->next=p->next;
}
else
{
desktop=p->next;
}
p->next=NULL;
waktual->next=p;
waktual=p;
if (waktual->objects!=NULL)
{
o_start=waktual->objects;
o_aktual=NULL;
o_end=o_start;
while(o_end->next!=NULL) o_end=o_end->next;
}
else
{o_start=NULL;o_aktual=NULL;o_end=NULL;}
}
long desktop_add_window(WINDOW *w)
{
static long id_counter=0;
w->id=id_counter++;
w->next=NULL;
if (desktop==NULL)
{
waktual=w;
desktop=w;
}
else
{
if (o_aktual!=NULL)
{
EVENT_MSG msg;
msg.msg=E_LOST_FOCUS;
o_aktual->events[2]();
o_aktual->runs[2](&msg,o_aktual);
}
waktual->next=w;
waktual=w;
}
o_aktual=NULL;
o_end=NULL;
o_start=NULL;
return w->id;
}
WINDOW *find_window(long id)
{
WINDOW *p;
p=desktop;
while (p!=NULL && p->id!=id) p=p->next;
return p;
}
void absolute_window(WINDOW *w,OBJREC *o, int *x, int *y)
{
switch (o->align)
{
case 0:
case 1:*y=o->y+w->y;break;
case 2:
case 3:*y=(w->y+w->ys)-(o->y+o->ys);break;
}
switch (o->align)
{
case 0:
case 3:*x=o->x+w->x;break;
case 1:
case 2:*x=(w->x+w->xs)-(o->x+o->xs);break;
}
}
void disable_bar(int x,int y,int xs,int ys,word color)
{
int i,j;
word *a;
for (i=y;i<=y+ys;i++)
{
a=GetScreenAdr()+scr_linelen2*i+x;
for(j=x;j<=x+xs;j++)
{
*a=((*a & RGB555(30,30,30))+(color & RGB555(30,30,30)))>>1;
*a=((*a & RGB555(30,30,30))+(color & RGB555(30,30,30)))>>1;
a++;
}
}
}
void draw_object(WINDOW *w,OBJREC *o,char show)
{
int x, y;
int ok;
// WINDOW *ws;
if (o->draw_error==1) return;
o->draw_error=1;
ok=w->border3d.bsize;
absolute_window(w,o,&x,&y);
o->locx=x;o->locy=y;
if (o->xs<1 || o->ys<1)
{
o->draw_error=0;
return;
}
schovej_mysku();
draw_border(x,y,o->xs,o->ys,&o->border3d);
curcolor=o->color;
curfont=o->font;position(x,y);
memcpy(&charcolors,&o->f_color,sizeof(charcolors));
// ws=waktual;
// waktual=w;
o->runs[1](x,y,x+o->xs,y+o->ys,o);
// waktual=ws;
if (!o->enabled) disable_bar(x,y,o->xs,o->ys,o->color);
ukaz_mysku();
if (show) showview(x-ok,y-ok,o->xs+(ok<<1),o->ys+(ok<<1));
o->draw_error=0;
}
void redraw_object(OBJREC *o)
{
draw_object(waktual,o,1);
}
void redraw_window_call()
{
OBJREC *p;
schovej_mysku();
waktual->draw_event(waktual);
p=waktual->objects;
while (p!=NULL)
{
draw_object(waktual,p,0);
p=p->next;
}
ukaz_mysku();
show_window(waktual);
return;
}
void add_to_idlist(OBJREC *o)
{
TIDLIST *p,*q;
p=(TIDLIST *)getmem(sizeof(TIDLIST));
p->obj=o;
if (waktual->idlist==NULL)
{
p->next=NULL;
waktual->idlist=p;
return;
}
if (((waktual->idlist)->obj)->id>o->id)
{
p->next=waktual->idlist;
waktual->idlist=p;
return;
}
q=waktual->idlist;
while (q->next!=NULL && ((q->next)->obj)->id<o->id) q=q->next;
p->next=q->next;
q->next=p;
}
void define(int id,int x,int y,int xs,int ys,char align,void (*initproc)(OBJREC *),...)
{
OBJREC *o;
long *p;
o=(OBJREC *)getmem(sizeof(OBJREC));
o->x=x;o->y=y;o->xs=xs;o->ys=ys;
o->id=id;
o->runs[0]=empty1;
o->runs[1]=empty2;
o->runs[2]=empty3;
o->runs[3]=empty1;
o->autoresizex=0;
o->autoresizey=0;
o->events[0]=empty;
o->events[1]=empty;
o->events[2]=empty1;
o->events[3]=empty3;
o->enabled=1;
o->draw_error=0;
o->color=waktual->color;memcpy(o->f_color,f_default,sizeof(f_default));
memcpy(&(o->border3d),&noneborder,sizeof(CTL3D));
o->userptr=NULL;
o->align=align;
o->font=default_font;
o->datasize=0;
initproc(o);
if (o->datasize) o->data=(void *)getmem(o->datasize); else o->data=NULL;
p=(long *)&initproc;p++;
o->runs[0](o,p);
if (o->datasize && o->data==NULL) o->data=(void *)getmem(o->datasize);
o->next=NULL;
if (o_start==NULL)
{
o_start=o;
o_end=o;
o_aktual=NULL;
waktual->objects=o;
}
else
{
o_end->next=o;
o_end=o;
}
add_to_idlist(o);
}
CTL3D *border(word light,word shadow, word bsize, word btype)
{
static CTL3D p;
p.light=light;p.shadow=shadow;p.bsize=bsize;p.ctldef=btype;
return &p;
}
void property(CTL3D *ctl,word *font,FC_TABLE *fcolor,word color)
{
if (ctl!=NULL) memcpy(&o_end->border3d,ctl,sizeof(CTL3D));
if (font!=NULL) o_end->font=font;
if (fcolor!=NULL) memcpy(&o_end->f_color,fcolor,sizeof(FC_TABLE));
if (color!=0xffff) o_end->color=color;
}
FC_TABLE *flat_color(word color)
{
static FC_TABLE p;
p[0]=0xffff;
p[1]=color;p[2]=color;p[3]=color;p[4]=color;p[5]=color;p[6]=color;
return &p;
}
void aktivate_window(MS_EVENT *ms)
{
WINDOW *p,*q;
if (ms->event_type==1) return;
p=desktop;q=NULL;
while (p!=NULL)
{
if (ms->x>=p->x && ms->x<=p->x+p->xs && ms->y>=p->y && ms->y<=p->y+p->ys)
q=p;
p=p->next;
}
if (q==NULL) return;
if (q!=waktual)
{
select_window(q->id);
redraw_window();
return;
}
return;
}
void redraw_desktop_call(EVENT_MSG *msg,void **data)
{
WINDOW *w;
char *oz;
data;
if (msg->msg==E_INIT || msg->msg==E_DONE) return;
if (!force_redraw_desktop) return;
force_redraw_desktop=0;
schovej_mysku();
if (gui_background==NULL)
{
curcolor=DESK_TOP_COLOR;
bar(0,0,SCR_WIDTH_X,SCR_WIDTH_Y-1);
}
else
put_picture(0,0,gui_background);
oz=otevri_zavoru;
do_events();
*oz=1;
w=desktop;
while (w!=NULL)
{
OBJREC *p;
w->draw_event(w);
p=w->objects;
while (p!=NULL)
{
draw_object(w,p,0);
p=p->next;
}
w=w->next;
*oz=0;
do_events();
*oz=1;
}
send_message(E_REDRAW);
ukaz_mysku();
showview(0,0,0,0);
move_ms_cursor(0,0,1);
}
void redraw_desktop()
{
force_redraw_desktop=1;
}
void redraw_window()
{
redraw_window_call();
}
void close_window(WINDOW *w)
{
WINDOW *p;
OBJREC *q;
if (waktual==w && send_lost()) return;
if (w==waktual && waktual!=desktop)
{
p=desktop;
while (p->next!=waktual) p=p->next;
w->modal=0;
select_window(p->id);
}
if (w!=desktop)
{
p=desktop;
while (p->next!=w) p=p->next;
p->next=w->next;
}
else
{
desktop=w->next;
if (desktop==NULL) waktual=NULL;
}
while (w->objects!=NULL)
{
q=w->objects;
w->objects=q->next;
q->runs[3](q);
if (q->userptr!=NULL) free(q->userptr);
if (q->data!=NULL) free(q->data);
free(q);
}
while (w->idlist!=NULL)
{
TIDLIST *p;
p=w->idlist;
w->idlist=p->next;
free(p);
}
free(w);
if (desktop==NULL) exit_wait=1;
redraw_desktop();
}
//-------------------------------- GUI EVENTS -------------------------
char mouse_in_object(MS_EVENT *ms,OBJREC *o, WINDOW *w)
{
int x1, y1, x2, y2;
absolute_window(w,o,&x1,&y1);
x2=x1+o->xs;
y2=y1+o->ys;
if (ms->x>=x1 && ms->x<=x2 && ms->y>=y1 && ms->y<=y2)
return 1;
else
return 0;
}
OBJREC *get_last_id()
{
TIDLIST *p;
p=waktual->idlist;
while (p->next!=NULL) p=p->next;
return p->obj;
}
OBJREC *get_next_id(OBJREC *o)
{
TIDLIST *p;
p=waktual->idlist;
while (p!=NULL && p->obj!=o) p=p->next;
if (p==NULL) return NULL;
do
{
p=p->next;
if (p==NULL) p=waktual->idlist;
o=p->obj;
if (o->enabled && o->runs[2]!=empty3) return o;
}
while (1);
}
OBJREC *get_prev_id(OBJREC *o)
{
TIDLIST *p,*q;
p=waktual->idlist;
while (p!=NULL && p->obj!=o) p=p->next;
if (p==NULL) return NULL;
do
{
if (p==waktual->idlist)
{
p=waktual->idlist;
while (p->next!=NULL) p=p->next;
}
else
{
q=waktual->idlist;
while (q->next!=p) q=q->next;
p=q;
}
o=p->obj;
if (o->enabled && o->runs[2]!=empty3) return o;
}
while (1);
}
void do_it_events(EVENT_MSG *msg,void **user_data)
{
MS_EVENT *msev;
EVENT_MSG msg2;
char b;
static word cursor_tick=CURSOR_SPEED
OBJREC *p;
char *oz=otevri_zavoru;
user_data;
if (msg->msg==E_INIT) return;
if (desktop==NULL) {exit_wait=1;return;}
change_flag=0;f_cancel_event=0;
if (o_aktual!=NULL)o_aktual->events[0](msg,o_aktual);
if (msg->msg==E_MOUSE)
{
*oz=1;
msev=get_mouse(msg);
aktivate_window(msev);
if (o_aktual==NULL)
if (o_start!=NULL && (msev->tl1 || msev->tl2 || msev->tl3))
{
o_aktual=o_start;
while (o_aktual!=NULL && (!o_aktual->enabled || !mouse_in_object(msev,o_aktual,waktual) || o_aktual->runs[2]==empty3)) o_aktual=o_aktual->next;
if (o_aktual==NULL) return;
msg2.msg=E_GET_FOCUS;
o_aktual->runs[2](&msg2,o_aktual);
o_aktual->events[1]();
o_aktual->runs[2](msg,o_aktual);
}
else return;
else
{
if (o_aktual->enabled) b=mouse_in_object(msev,o_aktual,waktual);else b=0;
if (b)
o_aktual->runs[2](msg,o_aktual);
if ((msev->tl1 || msev->tl2 || msev->tl3)&& !b)
{
o_aktual->events[2]();
if (f_cancel_event) return;
msg2.msg=E_LOST_FOCUS;
o_aktual->runs[2](&msg2,o_aktual);
p=o_start;
while (p!=NULL && (!p->enabled || !mouse_in_object(msev,p,waktual) || p->runs[2]==empty3))
p=p->next;
if (p!=NULL) o_aktual=p;
msg2.msg=E_GET_FOCUS;
o_aktual->runs[2](&msg2,o_aktual);
o_aktual->events[1]();
if (p!=NULL) o_aktual->runs[2](msg,o_aktual);
}
}
}
if (msg->msg==E_KEYBOARD)
{
*oz=1;
if (o_aktual!=NULL)
{
o_aktual->runs[2](msg,o_aktual);
}
if ((*(int *)msg->data>>8)==0xf && waktual->idlist!=NULL)
{
if (o_aktual==NULL) o_aktual=get_last_id();
if (o_aktual!=NULL)
{
f_cancel_event=0;
o_aktual->events[2]();
if (f_cancel_event) return;
msg2.msg=E_LOST_FOCUS;
o_aktual->runs[2](&msg2,o_aktual);
}
if((*(int *)msg->data & 0xff)==9) o_aktual=get_next_id(o_aktual);
else o_aktual=get_prev_id(o_aktual);
if (o_aktual!=NULL)
{
msg2.msg=E_GET_FOCUS;
o_aktual->runs[2](&msg2,o_aktual);
o_aktual->events[1]();
}
}
}
if (msg->msg==E_TIMER && o_aktual!=NULL)
{
o_aktual->runs[2](msg,o_aktual);
if (!(cursor_tick--))
{
msg->msg=E_CURSOR_TICK;
o_aktual->runs[2](msg,o_aktual);
o_aktual->events[0](msg,o_aktual);
cursor_tick=CURSOR_SPEED;
}
}
if (msg->msg==E_GUI)
{
OBJREC *o;
EVENT_MSG msg2;
int *p;
p=msg->data;
o=find_object(waktual,*p++);
if (o!=NULL)
{
msg2.msg=*p++;
msg2.data=p;
o->runs[2](&msg2,o);
o->events[0](&msg,o_aktual);
}
}
if (msg->msg==E_CHANGE)
run_background(o_aktual->events[3]);
if (change_flag) send_message(E_CHANGE);
}
void install_gui(void)
{
desktop_y_size = SCR_WIDTH_Y;
send_message(E_ADD,E_MOUSE,do_it_events);
send_message(E_ADD,E_KEYBOARD,do_it_events);
send_message(E_ADD,E_CHANGE,do_it_events);
send_message(E_ADD,E_TIMER,do_it_events);
send_message(E_ADD,E_GUI,do_it_events);
send_message(E_ADD,E_IDLE,redraw_desktop_call);
}
void uninstall_gui(void)
{
send_message(E_DONE,E_MOUSE,do_it_events);
send_message(E_DONE,E_KEYBOARD,do_it_events);
send_message(E_DONE,E_CHANGE,do_it_events);
send_message(E_DONE,E_TIMER,do_it_events);
send_message(E_DONE,E_GUI,do_it_events);
send_message(E_DONE,E_IDLE,redraw_desktop_call);
}
//send_message(E_GUI,cislo,E_UDALOST,data....)
void on_change(void (*proc)())
{
o_end->events[3]=proc;
}
void on_enter(void (*proc)())
{
o_end->events[1]=proc;
}
void on_exit(void (*proc)())
{
o_end->events[2]=proc;
}
void on_event(void (*proc)())
{
o_end->events[0]=proc;
}
void terminate(void)
{
exit_wait=1;
}
void set_change(void)
{
change_flag=1;
}
void set_window_modal(void)
{
waktual->modal=1;
}
void set_object_value(char redraw,OBJREC *o,void *value)
{
if (memcmp(o->data,value,o->datasize))
{
memcpy(o->data,value,o->datasize);
if (redraw) redraw_object(o);
}
}
OBJREC *find_object(WINDOW *w,int id)
{
OBJREC *p;
p=w->objects;
if (p==NULL) return NULL;
while (p!=NULL && p->id!=id) p=p->next;
return p;
}
OBJREC *find_object_desktop(int win_id,int obj_id,WINDOW **wi)
{
WINDOW *w;
OBJREC *o;
if (win_id<0) return NULL;
if (win_id==0) w=waktual;
else
w=find_window(win_id);
if (w==NULL) return NULL;
o=find_object(w,obj_id);
*wi=w;
return o;
}
void set_value(int win_id,int obj_id,void *value)
{
OBJREC *o;
WINDOW *w;
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL)return;
set_object_value((w==waktual),o,value);
}
void set_default(void *value)
{
set_object_value(0,o_end,value);
}
void goto_control(int obj_id)
{
EVENT_MSG msg;
if (send_lost()) return;
o_aktual=find_object(waktual,obj_id);
msg.msg=E_GET_FOCUS;
o_aktual->events[0](&msg,o_aktual);
o_aktual->runs[2](&msg,o_aktual);
}
void c_set_value(int win_id,int obj_id,int cnst)
{
OBJREC *o;
WINDOW *w;
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL)return;
set_object_value((w==waktual),o,&cnst);
}
void c_default(int cnst)
{
set_object_value(0,o_end,&cnst);
}
int f_get_value(int win_id,int obj_id)
{
OBJREC *o;
WINDOW *w;
int v;
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL) return 0;
memcpy(&v,o->data,o->datasize);
return v;
}
void get_value(int win_id,int obj_id,void *buff)
{
OBJREC *o;
WINDOW *w;
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL)return;
memcpy(buff,o->data,o->datasize);
}
void cancel_event()
{
f_cancel_event=1;
}
void set_enable(int win_id,int obj_id,int condition)
{
OBJREC *o;
WINDOW *w;
condition=(condition!=0);
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL) return;
if (o==o_aktual)
if (send_lost()) return;
else
o_aktual=NULL;
if (o->enabled!=condition)
{
o->enabled=condition;
if (w==waktual) redraw_object(o);
}
}
void close_current()
{
close_window(waktual);
}
void background_runner(EVENT_MSG *msg,void **prog)
{
register void (*p)();
char i=1;
if (msg->msg==E_INIT)
{
memcpy(prog,msg->data,4);
return;
}
if (msg->msg==E_DONE)
{
*prog=NULL;
return;
}
p=*prog;
p();
i=0;
msg->msg=-2;
}
void run_background(void (*p)())
{
send_message(E_ADD,E_IDLE,background_runner,p);
}
void movesize_win(WINDOW *w, int newx,int newy, int newxs, int newys)
{
int xsdif,ysdif;
OBJREC *p;
if (newxs<w->minsizx) newxs=w->minsizx;
if (newys<w->minsizy) newys=w->minsizy;
if (newxs>=(SCR_WIDTH_X-2*w->border3d.bsize)) newxs=(SCR_WIDTH_X-2*w->border3d.bsize)-1;
if (newys+2>=(desktop_y_size-2*w->border3d.bsize)) newys=(desktop_y_size-2*w->border3d.bsize)-2;
xsdif=newxs-w->xs;
ysdif=newys-w->ys;
p=w->objects;
while (p!=NULL)
{
if (p->autoresizex) p->xs+=xsdif;
if (p->autoresizey) p->ys+=ysdif;
p=p->next;
}
w->x=newx;
w->y=newy;
w->xs=newxs;
w->ys=newys;
check_window(w);
}

166
libs/gui.h Normal file
View file

@ -0,0 +1,166 @@
#define E_MS_CLICK 50
#define E_MS_MOVE 51
#define E_GET_FOCUS 52
#define E_LOST_FOCUS 53
#define E_KEY_PRESS 54
#define E_CHANGE 55
#define E_CURSOR_TICK 56
#define E_REDRAW 57 //redraw desktop
#define E_GUI 58 //direct enter to gui system
#define E_CONTROL 59 //User defined feature, enables direct controling desktop objects
#define CURSOR_SPEED 5;
#define get_title(title) (char *)*(long *)(title);
#define DESK_TOP_COLOR RGB555(0,15,15);
#define MINSIZX 60
#define MINSIZY 40
#define SCR_WIDTH_X DxGetResX()
#define SCR_WIDTH_Y DxGetResY()
typedef struct ctl3d
{
word light,shadow,bsize,ctldef;
}CTL3D;
typedef word FC_TABLE[7];
typedef FC_TABLE FC_PALETTE[16];
//Run_routs:
/* 0 - INIT
1 - DRAW
2 - EVENT
3 - DONE
0 - WHEN EVENT
1 - AFTER GOT FOCUS
2 - BEFORE LOST FOCUS
3 - WHEN VALUE CHANGED / WHEN AKTIVATE BUTTON
*/
//objects
/* prototypy jednotlivych funkci
INIT(OBJREC *object,VOID *initparms);
DRAW(int x1,int y1,int x2,int y2,OBJREC *object);
EVENT(EVENT_MSG *msg, OBJREC *object);
DONE(OBJREC *object);
*/
typedef void (*RUN_ROUTS[4])();
typedef struct objrec
{
short x,y,xs,ys;
CTL3D border3d;
word color;
word id;
char align,autoresizex,autoresizey;
char enabled;
short locx,locy;
long datasize;
void *data;
FC_TABLE f_color;
word *font;
void *userptr;
RUN_ROUTS runs;
RUN_ROUTS events;
char draw_error; //1 znamena ze objekt zpusobil chybu a nebude vykreslovan
struct objrec *next;
}OBJREC;
// align urcuje vzhledem ke ktermu rohu je vypocet souradnic vztazen
/* align = 0 levy horni roh
align = 1 pravy horni roh
align = 2 pravy dolni roh
align = 3 levy dolni roh
autoresize=1 znamena, ze object zmeni svou velikost tak aby jeho
pravy dolni roh sledoval pravy dolni roh okna a levy horni roh sledoval
levy horni roh okna
*/
typedef struct tidlist
{
struct tidlist *next;
OBJREC *obj;
}TIDLIST;
typedef struct window
{
short x,y,xs,ys;
CTL3D border3d;
word color;
OBJREC *objects;
long id;
char modal,minimized,popup;
word minsizx,minsizy;
char *window_name;
void (*draw_event)(struct window *);
struct window *next;
TIDLIST *idlist;
}WINDOW;
extern WINDOW *desktop,*waktual;
extern OBJREC *o_aktual,*o_end,*o_start;
extern CTL3D noneborder;
extern FC_TABLE f_default;
extern word desktop_y_size;
//extern char change_flag;
extern word *default_font;
extern void *gui_background;
void draw_border(integer x,integer y,integer xs,integer ys,CTL3D *btype);
WINDOW *create_window(int x,int y, int xs, int ys, word color, CTL3D *okraj);
long desktop_add_window(WINDOW *w);
void select_window(long id);
WINDOW *find_window(long id);
void redraw_object(OBJREC *o);
void redraw_window();
void define(int id,int x,int y,int xs,int ys,char align,void (*initproc)(OBJREC *),...);
CTL3D *border(word light,word shadow, word bsize, word btype);
void property(CTL3D *ctl,word *font,FC_TABLE *fcolor,word color);
FC_TABLE *flat_color(word color);
void aktivate_window(MS_EVENT *ms);
void redraw_desktop();
void close_window(WINDOW *w);
void close_current();
void check_window(WINDOW *w);
void install_gui(void);
void uninstall_gui(void);
void on_control_change(void (*proc)());
void on_control_enter(void (*proc)());
void on_control_exit(void (*proc)());
void on_control_event(void (*proc)());
void terminate_gui(void);
void set_change(void);
void set_value(int win_id,int obj_id,void *value);
void set_default(void *value);
void c_set_value(int win_id,int obj_id,int cnst);
void c_default(int cnst);
int f_get_value(int win_id,int obj_id);
void get_value(int win_id,int obj_id,void *buff);
void cancel_event();
OBJREC *find_object(WINDOW *w,int id);
void set_window_modal(void);
void set_enable(int win_id,int obj_id,int condition);
void run_background(void (*p)());
void disable_bar(int x,int y,int xs,int ys,word color);
void movesize_win(WINDOW *w, int newx,int newy, int newxs, int newys);
void goto_control(int obj_id);

164
libs/inicfg.c Normal file
View file

@ -0,0 +1,164 @@
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <strlite.h>
#include <inicfg.h>
TSTR_LIST read_config(const char *filename)
{
FILE *f;
TSTR_LIST ls;
char buff[256];
f=fopen(filename,"r");
if (f==NULL) return NULL;
ls=create_list(256);
while (!feof(f))
{
char *c;
buff[0]=0;
if (fgets(buff,256,f)==NULL) break;
c=strchr(buff,'\n');if (c!=NULL) *c=0;
if (ferror(f))
{
release_list(ls);
fclose(f);
return NULL;
}
str_add(&ls,buff);
}
fclose(f);
return ls;
}
TSTR_LIST merge_configs(TSTR_LIST target, TSTR_LIST source)
{
char buff[256];
int i;
char *c;
buff[255]=0;
for (i=0;i<str_count(source);i++) if (source[i])
{
strncpy(buff,source[i],255);
c=strchr(buff,' ');
if (c!=NULL)
{
int p;
*c=0;
p=find_ini_field(target,buff);
if (p==-1)
{
str_add(&target,source[i]);
}
else
{
str_replace(&target,p,source[i]);
}
}
}
return target;
}
char comcmp(const char *text,const char *command)
{
while (toupper(*text)==toupper(*command)) text++,command++;
if (*command==0 && *text==' ') return 1;
return 0;
}
int find_ini_field(TSTR_LIST ls,const char *name)
{
const char *a;
char *b;
int i,cnt=str_count(ls);
for (i=0;i<cnt;i++) if (ls[i]!=NULL)
{
a=name;
b=ls[i];
while (*b==32) b++;
if (*b==';') continue;
if (comcmp(b,a)) return i;
}
return -1;
}
void add_field_txt(TSTR_LIST *ls,const char *name,const char *text)
{
int i;
char *d;
d=alloca(strlen(name)+strlen(text)+2);
sprintf(d,"%s %s",name,text);
i=find_ini_field(*ls,name);
if (i==-1) str_add(ls,d);
else
str_replace(ls,i,d);
}
void add_field_num(TSTR_LIST *ls,const char *name,long number)
{
char buff[20];
itoa(number,buff,10);
add_field_txt(ls,name,buff);
}
int save_config(TSTR_LIST ls,const char *filename)
{
int i,cnt,err=0;
FILE *f;
f=fopen(filename,"w");
if (f==NULL) return -1;
cnt=str_count(ls);
for(i=0;i<cnt && !err;i++) if (ls[i]!=NULL)
{
if (fputs(ls[i],f)==EOF) err=-1;
putc('\n',f);
}
fclose(f);
return err;
}
const char *get_text_field(TSTR_LIST ls,const char *name)
{
int i;
char *c;
if (ls==NULL) return NULL;
i=find_ini_field(ls,name);if (i==-1) return NULL;
c=ls[i];
c=strchr(c,' ');if (c!=NULL) while (*c==' ') c++;
else c=strchr(ls[i],0);
return c;
}
int get_num_field(TSTR_LIST ls,const char *name,int *num)
{
const char *c;
c=get_text_field(ls,name);
if (c==NULL) return -1;
if (sscanf(c,"%d",num)!=1) return -1;
return 0;
}
void process_ini(TSTR_LIST ls,void (*process)(const char *line))
{
char *c;
int i,cnt;
cnt=str_count(ls);
for(i=0;i<cnt;i++) if (ls[i]!=NULL)
{
c=ls[i];
while (*c==' ') c++;
if (*c==';') continue;
process(c);
}
}

10
libs/inicfg.h Normal file
View file

@ -0,0 +1,10 @@
TSTR_LIST read_config(const char *filename);
void add_field_txt(TSTR_LIST *ls,const char *name,const char *text);
void add_field_num(TSTR_LIST *ls,const char *name,long number);
int save_config(TSTR_LIST ls,const char *filename);
const char *get_text_field(TSTR_LIST ls,const char *name);
int get_num_field(TSTR_LIST ls,const char *name,int *num);
void process_ini(TSTR_LIST ls,void (*process)(const char *line));
char comcmp(const char *text,const char *command);
TSTR_LIST merge_configs(TSTR_LIST target, TSTR_LIST source);
int find_ini_field(TSTR_LIST ls,const char *name);

280
libs/lex_lib.c Normal file
View file

@ -0,0 +1,280 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef struct lex_tree
{
char znak;
char *data;
struct lex_tree *left,*right,*middle;
char params;
}LEX_TREE;
LEX_TREE koren={0,NULL,NULL,NULL,NULL};
char cur_include[256];
char last_parms;
FILE *target_file;
void error_extend(char *file,int seek)
{
FILE *f;
int c,i=0,ls=0,ls0=0,ls1=0,ls2=0;
f=fopen(file,"r");
if (f==NULL) return;
c=getc(f);
while (c!=EOF && ls2<seek)
{
if (c=='\n')
{
ls=ls0,ls0=ls1;ls1=ls2;ls2=ftell(f);
i++;
}
c=getc(f);
}
printf("Chyba nastala v souboru '%s' na radce %d\n\n",file,i);
fseek(f,ls,SEEK_SET);
c=getc(f);
i=0;
while (c!=EOF && i<3)
{
putchar(c);
if (c=='\n') i++;
c=getc(f);
}
fclose(f);
}
void error(char *text,int seek)
{
printf("CHYBA: %s \n",text);
fcloseall();
error_extend(cur_include,seek);
exit(1);
}
char *lex_find_string(char *text,LEX_TREE **z)
//najde retezec a vraci *z jako ukazatel na uzel ve strome + retezec
//ukazujici na posledni znak ktery se neshodoval (\0 retezec nasel)
{
LEX_TREE *p;
p=&koren;
do
{
*z=p;
if (p->znak==*text)
{
if (!text[0]) break;
text++;
p=p->middle;
}
else if (p->znak>*text) p=p->left;
else p=p->right;
}
while (p!=NULL);
return text;
}
LEX_TREE *lex_add_string(char *text)
{
char *tp;
LEX_TREE *z,*p,*q,*s;
tp=lex_find_string(text,&z);
if (*tp!=z->znak)
{
s=q=(LEX_TREE *)malloc(sizeof(LEX_TREE));
memset(q,0,sizeof(LEX_TREE));
q->znak=*tp;
while (*tp)
{
tp++;
p=(LEX_TREE *)malloc(sizeof(LEX_TREE));
memset(p,0,sizeof(LEX_TREE));
p->znak=*tp;
q->middle=p;
q=p;
}
if (s->znak>z->znak) z->right=s;
else if (s->znak<z->znak) z->left=s;
}
return q;
}
void lex_add_data(char *name,char *data,char parms)
{
LEX_TREE *z;
char *d;
z=lex_add_string(name);
d=(char *)malloc(strlen(data)+1);
strcpy(d,data);
z->data=d;
z->params=parms;
}
char *lex_get_data(char *name)
{
LEX_TREE *z;
name=lex_find_string(name,&z);
if (*name) return NULL;
last_parms=z->params;
return z->data;
}
char isnum(char *c)
{
if (*c=='-') c++;
while (*c) if (!isdigit(*c++)) return 0;
return 1;
}
void open_include(char *name);
void xlat_text(FILE *source,FILE *target)
{
char s[256],c[256],*p;
int i=0,z;
int lastcom=0,count=0;
char cm[256];
while (i!=EOF)
{
while (((i=fgetc(source))<33 || i==',' || i=='(' || i==')') && i!=EOF ) if (i=='\n')
if (count && lastcom)
{
char c[255];
sprintf(c,"Nespr vn˜ po‡et parametr u p©¡kazu '%s'",cm);
error(c,ftell(source));
}
else
{
count=1;
lastcom=0;
}
if (i=='\'' || i=='"')
{
int j=i;
i=fgetc(source);
if (i=='\n') i=32;
fputc('$',target);
while (i!=j && i!=EOF)
{
fputc(i,target);
i=fgetc(source);
if (i=='\n') i=32;
}
fputc('\n',target);
if (i==EOF) i=0;else i=1;
fgetc(source);
count--;
continue;
}
else if (i==';')
{
while ((i=fgetc(source))!='\n' && i!=EOF);
continue;
}
else if (i=='!')
{
ungetc(i,source);
i=fscanf(source,"%[^\n]",s);
if (i==1) fprintf(target,"%s\n",s);
continue;
}
else
{
ungetc(i,source);
i=fscanf(source,"%[^ ,()\n\x9]",s);
}
if(i!=EOF && i==1)
{
if (s[0]=='#')
switch(s[1])
{
case 'i':fscanf(source,"%s",s);
open_include(s);
break;
case 'd':fscanf(source,"%s %[^\n]",s,c);
lex_add_data(s,c,0);
break;
case 'c':fscanf(source,"%s %s %d",s,c,&z);
lex_add_data(s,c,z);
break;
case 'e':fprintf(target,"\n");
break;
default: sprintf(c,"Neznamy prikaz '%s'",s);
error(c,ftell(source));
break;
}
else
{
if (isnum(s))
{
p=s;count--;
}
else
{
p=lex_get_data(s);
if (last_parms && !count)
{
count=lastcom=last_parms;
strcpy(cm,s);
}
else count--;
}
if (p!=NULL && i!=EOF) fprintf(target,"%s\n",p);
else
{
sprintf(c,"Nedefinovane jmeno '%s'",s);
error(c,ftell(source));
}
}
}
}
}
void open_include(char *name)
{
FILE *inc;
char *p;
inc=fopen(name,"r");
if (inc==NULL)
{
char s[256];
sprintf(s,"Knihovna nenalezena: %s",name);
error(s,0);
}
p=(char *)malloc(strlen(cur_include)+1);
strcpy(p,cur_include);
strcpy(cur_include,name);
xlat_text(inc,target_file);
fclose(inc);
strcpy(cur_include,p);
free(p);
}
main(int argc,char *argv[])
{
if (argc!=3)
{
puts("Program vyzaduje dva parametry: LEX_LIB source_file target_file");
exit(0);
}
target_file=fopen(argv[2],"w");
open_include(argv[1]);
fclose(target_file);
}

55
libs/lzwa.asm Normal file
View file

@ -0,0 +1,55 @@
.model small
.386
;16 bit line (de)comprimator
;
DGROUP group _DATA
extern _old_value:byte
extern _compress_dic:dword
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
public fast_expand_code_
fast_expand_code_:
cmp eax,256
jnc expand
mov esi,[edi]
inc dword ptr [edi]
mov bl,al
add al,_old_value
mov [esi],al
mov _old_value,al
ret
expand:
mov ebx,_compress_dic
lea ecx,[eax*8+ebx]
movzx eax,word ptr [ecx+4]
add [edi],eax
push eax
mov esi,[edi]
eloop:movzx eax,word ptr [ecx+2]
mov [esi],al
dec esi
movzx eax,word ptr [ecx]
lea ecx,[eax*8+ebx]
cmp eax,256
jnc eloop
mov bl,al
add al,_old_value
mov [esi],al
inc dword ptr [edi]
pop ecx
elp2:inc esi
add al,[esi]
mov [esi],al
dec ecx
jnz elp2
mov _old_value,al
ret
_TEXT ends
end

2
libs/mem.h Normal file
View file

@ -0,0 +1,2 @@
#include <string.h>
#include <malloc.h>

963
libs/memman.c Normal file
View file

@ -0,0 +1,963 @@
#include <skeldal_win.h>
#include "types.h"
#include <mem.h>
#include <dos.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include "memman.h"
#include <time.h>
//#include <i86.h>
#include "swaper.c"
#include <fcntl.h>
#include <io.h>
#include <SYS\STAT.H>
#define DPMI_INT 0x31
#define LOAD_BUFFER 4096
#undef malloc
void bonz_table();
#define NON_GETMEM_RESERVED (4*1024)
char **mman_pathlist=NULL;
static char swap_status=0;
static int swap;
char mman_patch=0;
int memman_handle;
static int max_handle=0;
//static FILE *log;
void (*mman_action)(int action)=NULL;
long last_load_size;
void get_mem_info(MEMORYSTATUS *mem)
{
mem->dwLength=sizeof(*mem);
GlobalMemoryStatus(mem);
}
void standard_mem_error(size_t size)
{
char buff[256];
SEND_LOG("(ERROR) Memory allocation error detected, %u bytes missing",size,0);
DXCloseMode();
sprintf(buff,"Memory allocation error\n Application can't allocate %u bytes of memory (%xh)\n",size,memman_handle);
MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP);
exit(1);
}
void load_error(char *filename)
{
char buff[256];
SEND_LOG("(ERROR) Load error detected, system can't load file: %s",filename,0);
#ifdef LOGFILE
// bonz_table();
#endif
DXCloseMode();
sprintf(buff,"Load error while loading file: %s", filename);
MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP);
exit(1);
}
void standard_swap_error()
{
char buff[256];
DXCloseMode();
sprintf(buff,"Swap error. Maybe disk is full");
MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP);
exit(1);
}
void (*mem_error)(size_t)=standard_mem_error;
void (*swap_error)()=standard_swap_error;
void *getmem(long size)
{
void *p,*res;
if (!size) return NULL;
do
{
res=malloc(NON_GETMEM_RESERVED);
if (res!=NULL)
{
p=(void *)malloc(size);
free(res);
}
else p=NULL;
if (p==NULL) mem_error(size);
}
while (p==NULL);
// SEND_LOG("(ALLOC) **** Alloc: %p size %d",p,*((long *)p-1));
return p;
}
void *load_file(char *filename)
{
int f;
long size,*p;
if (mman_action!=NULL) mman_action(MMA_READ);
SEND_LOG("(LOAD) Loading file '%s'",filename,0);
f=open(filename,O_BINARY | O_RDONLY);
if (f==-1) load_error(filename);
size=filelength(f);
p=(void *)getmem(size);
if (read(f,p,size)!=size) load_error(filename);
close(f);
last_load_size=size;
return p;
}
//--------------- BLOCK MASTER OPERATION SYSTEM --------------------------
//--------------- part: MEMORY MANAGER -----------------------------------
typedef struct tnametable
{
char name[12];
long seek;
}TNAMETABLE;
static long *grptable,grptabsiz;
static TNAMETABLE *nametable;
static int nmtab_size;
static int next_name_read=0;
static int last_group;
char *main_file_name=NULL;
handle_groups _handles;
static int bmf=-1;
static int patch=-1;
unsigned long bk_global_counter=0;
char *swap_path;
#ifdef LOGFILE
static void bonz_table()
{
int i;
if (bmf==-1) return;
for(i=0;i<nmtab_size;i++)
{
fprintf(stderr,"%-12.12s %12d\n",nametable[i].name,nametable[i].seek);
}
}
#endif
static int test_file_exist_DOS(int group,char *filename)
{
char *f;
f=alloca(strlen(mman_pathlist[group])+strlen(filename)+1);
strcpy(f,mman_pathlist[group]);
strcat(f,filename);
if (access(f,0)) return 0;
return 1;
}
void load_grp_table()
{
long i;
SEND_LOG("(LOAD) Loading Group Table",0,0);
lseek(bmf,4,SEEK_SET);
read(bmf,&i,4);
grptable=(long *)getmem(i+4);
lseek(bmf,0,SEEK_SET);
read(bmf,grptable,i);
grptabsiz=i;
for(i=0;i<(grptabsiz>>3);i++) grptable[i*2+1]=(grptable[i*2+1]-grptabsiz)>>4;
SEND_LOG("(LOAD) Group Table Loaded",0,0);
}
void load_file_table()
{
int strsize;
void *p;
SEND_LOG("(LOAD) Loading File Table",0,0);
lseek(bmf,grptabsiz,SEEK_SET);
lseek(bmf,12,SEEK_CUR);
read(bmf,&strsize,4);
strsize-=grptabsiz;
lseek(bmf,grptabsiz,SEEK_SET);
p=getmem(strsize);memcpy(&nametable,&p,4);
read(bmf,nametable,strsize);
nmtab_size=strsize/sizeof(*nametable);
SEND_LOG("(LOAD) File Table Loaded",0,0);
}
int find_name(int group,char *name)
{
int i;
for(i=0;i<(grptabsiz>>2);i+=2)
{
if (grptable[i]==group) break;
}
if ((grptabsiz>>2)<=i) return -1;
for(i=grptable[i+1];i<nmtab_size;i++)
if (!strncmp(nametable[i].name,name,12)) break;
if (i==nmtab_size) return -1;
return i;
}
int get_file_entry(int group,char *name)
{
int i;
char ex;
if (mman_patch) ex=test_file_exist_DOS(group,name);else ex=0;
if (ex || bmf==0) return 0;
i=find_name(group,name);
if (i==-1) return 0;
return nametable[i].seek;
}
int swap_block(THANDLE_DATA *h)
{
long wsize,pos;
if (mman_action!=NULL) mman_action(MMA_SWAP);
if (swap==-1) return -1;
if (h->flags & BK_HSWAP) pos=h->seekpos; else pos=swap_add_block(h->size);
lseek(swap,0,SEEK_END);
wsize=tell(swap);
if (wsize<pos) write(swap,NULL,pos-wsize);
lseek(swap,pos,SEEK_SET);
SEND_LOG("(SWAP) Swaping block '%-.12hs'",h->src_file,0);
wsize=write(swap,h->blockdata,h->size);
swap_status=1;
if ((unsigned)wsize==h->size)
{
h->seekpos=pos;
if (h->flags & BK_PRELOAD) h->flags&=~BK_SWAPABLE;
h->flags|=BK_HSWAP;
return 0;
}
else
{
SEND_LOG("(SWAP) Swap failed!",0,0);
swap_error();
}
swap_free_block(pos,h->size);
return -1;
}
THANDLE_DATA *get_handle(int handle)
{
int group,list;
group=handle/BK_MINOR_HANDLES;
list=handle % BK_MINOR_HANDLES;
if (_handles[group]==NULL)
{
_handles[group]=(handle_list *)getmem(sizeof(handle_list));
memset(_handles[group],0,sizeof(handle_list));
}
if (handle>max_handle) max_handle=handle;
return ((THANDLE_DATA *)_handles[group])+list;
}
void heap_error(size_t size) //heap system
{
int i,j;
char swaped=0;
unsigned long maxcounter=0;
THANDLE_DATA *sh;
char repeat=0,did=0;
THANDLE_DATA *lastblock=NULL;
char *last_free=NULL;
int num;
do
{
maxcounter=0;
sh=NULL;
repeat=0;did=0;
for(i=0;i<BK_MAJOR_HANDLES;i++)
if (_handles[i]!=NULL)
{
unsigned long c,max=0xffffffff,d;
for (j=0;j<BK_MINOR_HANDLES;j++)
{
THANDLE_DATA *h;
h=((THANDLE_DATA *)_handles[i]+j);
c=bk_global_counter-h->counter;
if (h->status==BK_PRESENT && ~h->flags & BK_LOCKED)
if (last_free!=NULL)
{
d=(char *)h->blockdata-last_free;
if (d<max) sh=h,max=d,did=1,num=i*BK_MINOR_HANDLES+j;
}
else if (c>maxcounter)
{
maxcounter=c;
sh=h;
did=1;
num=i*BK_MINOR_HANDLES+j;
}
}
}
if (lastblock==sh)
{
did=0;repeat=0;
}
if (did)
{
size-=sh->size;
last_free=sh->blockdata;
if (sh->flags & BK_SWAPABLE)
{
if (swap_block(sh)) //pri neuspechu o ulozeni je nalezen blok jiny
{
sh->counter=bk_global_counter;
repeat=1;
}
else
{
free(sh->blockdata);
sh->status=BK_SWAPED;
swaped=1;
}
}
else
{
if (sh->flags & BK_PRELOAD) sh->status=BK_SWAPED;
else sh->status=BK_NOT_LOADED;
free(sh->blockdata);
if (mman_action!=NULL) mman_action(MMA_FREE);
}
}
else
standard_mem_error(size);
lastblock=sh;
}
while (repeat || size>0);
// if (swaped) _dos_commit(swap);
}
THANDLE_DATA *kill_block(int handle)
{
THANDLE_DATA *h;
h=get_handle(handle);if (h->status==BK_NOT_USED) return h;
if (h->flags & BK_LOCKED)
{
SEND_LOG("(ERROR) Unable to kill block! It is LOCKED! '%-.12hs' (%04X)",h->src_file,handle);
return NULL;
}
SEND_LOG("(KILL) Killing block '%-.12hs' (%04X)",h->src_file,handle);
if (h->status==BK_SAME_AS) return h;
if (h->status==BK_PRESENT) free(h->blockdata);
if (h->flags & BK_HSWAP) swap_free_block(h->seekpos,h->size);
h->status=BK_NOT_LOADED;
h->flags&=~BK_HSWAP;
return h;
}
THANDLE_DATA *zneplatnit_block(int handle)
{
THANDLE_DATA *h;
h=kill_block(handle);
if (h->status==BK_SAME_AS)
return zneplatnit_block(h->seekpos);
if (h->src_file[0]) h->seekpos=get_file_entry(h->path,h->src_file);
return h;
}
void init_manager(char *filename,char *swp) // filename= Jmeno datoveho souboru nebo NULL pak
// se pouzije DOS
// swp je cesta do TEMP adresare
{
next_name_read=0;
last_group=0;
memset(_handles,0,sizeof(_handles));
if (filename!=NULL)
{
bmf=open(filename,O_BINARY | O_RDONLY);
if (bmf!=-1)
{
main_file_name=(char *)getmem(strlen(filename)+1);
strcpy(main_file_name,filename);
load_grp_table();
load_file_table();
}
else
main_file_name=NULL;
}
else
main_file_name=NULL;
mem_error=heap_error;
if (swp!=NULL)
{
swap=open(swp,O_BINARY | O_RDWR | O_CREAT | O_TRUNC,_S_IREAD | _S_IWRITE);
swap_init();
}
else
swap=-1;
}
void *load_swaped_block(THANDLE_DATA *h)
{
void *i;
if (mman_action!=NULL) mman_action(MMA_SWAP_READ);
i=getmem(h->size);
SEND_LOG("(LOAD)(SWAP) Loading block from swap named '%-.12hs'",h->src_file,0);
lseek(swap,h->seekpos,SEEK_SET);
read(swap,i,h->size);
h->status=BK_PRESENT;
return i;
}
int find_same(char *name,void *decomp)
{
THANDLE_DATA *p;
int i,j;
decomp;
if (name[0]==0) return -1;
for(i=0;i<BK_MAJOR_HANDLES;i++)
if (_handles[i]!=NULL)
{
p=(THANDLE_DATA *)(_handles[i]);
for(j=0;j<BK_MINOR_HANDLES;j++)
if ((!strncmp(p[j].src_file,name,12))&& (p[j].loadproc==decomp)) return i*BK_MINOR_HANDLES+j;
}
return -1;
}
int find_handle(char *name,void *decomp)
{
return find_same(name,decomp);
}
int test_file_exist(int group,char *filename)
{
if (find_name(group,filename)==-1) return test_file_exist_DOS(group,filename);
return 1;
}
THANDLE_DATA *def_handle(int handle,char *filename,void *decompress,char path)
{
THANDLE_DATA *h;
int i;
i=find_same(filename,decompress);
h=get_handle(handle);
if (i==handle) return h;
if (kill_block(handle)==NULL)
{
SEND_LOG("(ERROR) File/Block can't be registred, handle is already in use '%-.12hs' handle %04X",filename,handle);
return NULL;
}
if (i!=-1 && i!=handle)
{
h->status=BK_SAME_AS;
h->seekpos=i;
return h;
}
memcpy(h->src_file,filename,12);
h->seekpos=0;
strupr(h->src_file);
h->loadproc=decompress;
if (filename[0])
h->seekpos=get_file_entry(path,h->src_file);
SEND_LOG("(REGISTER) File/Block registred '%-.12hs' handle %04X",h->src_file,handle);
SEND_LOG("(REGISTER) Seekpos=%d",h->seekpos,0);
h->flags=0;
h->path=path;
if (h->status!=BK_DIRLIST) h->status=BK_NOT_LOADED;
h->counter=bk_global_counter++;
return h;
}
void *afile(char *filename,int group,long *blocksize)
{
char *c,*d;
long entr;
void *p;
d=alloca(strlen(filename)+1);
strcpy(d,filename);
strupr(d);
if (mman_patch && test_file_exist_DOS(group,d)) entr=0;
else entr=get_file_entry(group,d);
if (entr!=0)
{
int hnd;
SEND_LOG("(LOAD) Afile is loading file '%s' from group %d",d,group);
if (entr<0) entr=-entr,hnd=patch;else hnd=bmf;
lseek(hnd,entr,SEEK_SET);
read(hnd,blocksize,4);
p=getmem(*blocksize);
read(hnd,p,*blocksize);
}
else if (mman_pathlist!=NULL)
{
SEND_LOG("(LOAD) Afile is loading file '%s' from disk",d,group);
c=alloca(strlen(filename)+strlen(mman_pathlist[group])+2);
c=strcat(strcpy(c,mman_pathlist[group]),filename);
p=load_file(c);
*blocksize=last_load_size;
}
else return NULL;
return p;
}
void *ablock(int handle)
{
THANDLE_DATA *h;
sem:
h=get_handle(handle);
if (memman_handle!=handle || h->status!=BK_PRESENT) h->counter=bk_global_counter++;
memman_handle=handle;
if (h->status==BK_SAME_AS)
{
handle=h->seekpos;
goto sem;
}
if (h->status==BK_PRESENT) return h->blockdata;
if (h->status==BK_DIRLIST)
{
free(h->blockdata);h->status=BK_NOT_LOADED;
}
if (h->status==BK_NOT_LOADED)
{
void *p;long s;
char c[200];
SEND_LOG("(LOAD) Loading file as block '%-.12hs' %04X",h->src_file,handle);
if (h->seekpos==0)
{
if (h->src_file[0]!=0)
{
if (mman_action!=NULL) mman_action(MMA_READ);
strcpy(c,mman_pathlist[h->path]);strcat(c,h->src_file);
c[strlen(mman_pathlist[h->path])+12]='\0';
p=load_file(c);
s=last_load_size;
}
else
{
p=NULL;
s=0;
}
if (h->loadproc!=NULL) h->loadproc(&p,&s);
h->blockdata=p;
h->status=BK_PRESENT;
h->size=s;
return p;
}
else
{
int entr=h->seekpos,hnd;
if (mman_action!=NULL) mman_action(MMA_READ);
if (entr<0) entr=-entr,hnd=patch;else hnd=bmf;
lseek(hnd,entr,SEEK_SET);
read(hnd,&s,4);
p=getmem(s);
read(hnd,p,s);
if (h->loadproc!=NULL) h->loadproc(&p,&s);
h->blockdata=p;
h->status=BK_PRESENT;
h->size=s;
return p;
}
}
//tato cast programu bude jeste dodelana - else ....
if (h->status==BK_SWAPED)
{
return h->blockdata=load_swaped_block(h);
}
return NULL;
}
void alock(int handle)
{
THANDLE_DATA *h;
h=get_handle(handle);
if (!h->lockcount)
{
h->flags|=BK_LOCKED;
if (h->status==BK_SAME_AS) alock(h->seekpos);
}
h->lockcount++;
//SEND_LOG("(LOCK) Handle locked %04X (count %d)",handle,h->lockcount);
}
void aunlock(int handle)
{
THANDLE_DATA *h;
h=get_handle(handle);
if (h->lockcount) h->lockcount--;else return;
if (!h->lockcount)
{
h->flags&=~BK_LOCKED;
if (h->status==BK_SAME_AS) aunlock(h->seekpos);
}
//SEND_LOG("(LOCK) Handle unlocked %04X (count %d)",handle,h->lockcount);
}
void aswap(int handle)
{
THANDLE_DATA *h;
h=get_handle(handle);
h->flags|=BK_SWAPABLE;
if (h->status==BK_SAME_AS) aswap(h->seekpos);
}
void aunswap(int handle)
{
THANDLE_DATA *h;
h=get_handle(handle);
h->flags|=BK_SWAPABLE;
if (h->status==BK_SAME_AS) aunswap(h->seekpos);
}
void apreload(int handle)
{
THANDLE_DATA *h;
h=get_handle(handle);
if (h->src_file[0] && h->status!=BK_SAME_AS)
{
if (!(h->flags & BK_PRELOAD) || !(h->flags & BK_HSWAP)) h->flags|=BK_SWAPABLE | BK_PRELOAD;
ablock(handle);
}
}
static long *apr_sign=NULL;
static long max_sign;
void apreload_sign(int handle,int max_handle)
{
THANDLE_DATA *h;
if (apr_sign==NULL)
{
apr_sign=NewArr(long,max_handle);
memset(apr_sign,0x7f,sizeof(long)*max_handle);
max_sign=max_handle;
}
if (handle>=max_sign)
{
apreload(handle);
return;
}
h=get_handle(handle);
if (h->src_file[0] && h->status!=BK_SAME_AS && h->status!=BK_NOT_USED)
if (!(h->flags & BK_PRELOAD) || !(h->flags & BK_HSWAP)) apr_sign[handle]=h->seekpos;
}
static int apreload_sort(const void *val1,const void *val2)
{
long vl1,vl2;
vl1=apr_sign[*(word *)val1];
vl2=apr_sign[*(word *)val2];
return (vl1>vl2)-(vl1<vl2);
}
void apreload_start(void (*percent)(int cur,int max))
{
word *p;
int i;
int c,z;
swap_status=0;
p=NewArr(word,max_sign);
for(i=0;i<max_sign;i++) p[i]=i;
qsort(p,max_sign,sizeof(word),apreload_sort);
for(i=0,c=0;i<max_sign;i++) if (apr_sign[p[i]]==0x7f7f7f7f)p[i]=-1;else c++;
for(i=0,z=0;i<max_sign;i++) if (p[i]!=-1)
{
apreload(p[i]);
percent(z++,swap_status?c+max_sign*2:c);
}
if (swap_status)
for(i=0;i<max_sign;i++)
{
THANDLE_DATA *h=get_handle(p[i]);
if (h->status==BK_PRESENT) swap_block(h);
percent(c+i,c+max_sign);
}
// _dos_commit(swap);
free(apr_sign);
free(p);
apr_sign=NULL;
}
void undef_handle(int handle)
{
THANDLE_DATA *h;
h=get_handle(handle);
if (h->status!=BK_NOT_USED)
{
if (kill_block(handle)==NULL) return;
SEND_LOG("(REGISTER) File/Block unregistred %04X (%-.12hs)",handle,h->src_file);
}
h->src_file[0]=0;
h->seekpos=0;
h->flags=0;
h->status=BK_NOT_USED;
}
void close_manager()
{
int i,j;
for(i=0;i<BK_MAJOR_HANDLES;i++) if (_handles[i]!=NULL)
{
for(j=0;j<BK_MINOR_HANDLES;j ++) undef_handle(i*BK_MINOR_HANDLES+j);
free(_handles[i]);
}
free(main_file_name);
close(bmf);
if (swap!=-1) close(swap);
// fclose(log);
free(grptable); grptable=NULL;
free(nametable); nametable=NULL;
max_handle=0;
}
//------------------------------------------------------------
/*static void block()
{
/* static MEMINFO inf;
void *c;
static counter=0;
get_mem_info(&inf);
c=malloc(inf.LargestBlockAvail-1024);
counter++;
printf("%d. %d\n",counter,inf.LargestBlockAvail);
if (c!=NULL) block();
counter--;
free(c);
}*/
void display_status()
{
int i,j;
THANDLE_DATA *h;
char names[][5]={"MISS","*ok*","SWAP","????","PTR "};
char flags[]={"LS*PH"};
char copys[6]=" ";
char nname[14];
long total_data=0;
long total_mem=0;
MEMORYSTATUS mem;
int ln=0;
//block();
//getchar();
memset(nname,0,sizeof(nname));
for(i=0;i<BK_MAJOR_HANDLES;i++)
if (_handles[i]!=NULL)
{
for(j=0;j<BK_MINOR_HANDLES;j++)
{
h=get_handle(i*BK_MINOR_HANDLES+j);
if (h->status!=BK_NOT_USED && h->status!=BK_SAME_AS)
{
int k;
for(k=0;k<5;k++) copys[k]=h->flags & (1<<k)?flags[k]:'.';
if (h->src_file[0]) strncpy(nname,h->src_file,12);else strcpy(nname,"<local>");
printf("%04Xh ... %12s %s %s %08Xh %6d %10d %6d \n",i*BK_MINOR_HANDLES+j,
nname,names[h->status-1],
copys,(int)h->blockdata,h->size,h->counter,h->lockcount);
ln++;
total_data+=h->size;
if(h->status==BK_PRESENT)total_mem+=h->size;
if (ln%24==23)
{
char c;
printf("Enter to continue, q-quit:");
c=getchar();
if (c=='q' || c=='Q')
{
while (getchar()!='\n');
return;
}
}
}
}
}
get_mem_info(&mem);
printf("Data: %7d KB, Loaded: %7d KB, Largest free: %7d KB",total_data/1024,total_mem/1024,mem.dwAvailPageFile/1024);
while (getchar()!='\n');
}
void *grealloc(void *p,long size)
{
void *q;
long scop;
if (!size)
{
free(p);
return NULL;
}
/*q=realloc(p,size);
if (q!=NULL)
{
SEND_LOG("(ALLOC) **** Realloc: New %p size %d\n",q,*((long *)q-1));
return q;
}*/
q=getmem(size);
if (p==NULL) return q;
scop=_msize(p);
if (scop>size) scop=size;
memmove(q,p,scop);
free(p);
return q;
}
char *read_next_entry(char mode)
{
if (mode==MMR_FIRST) next_name_read=0;
if (main_file_name==NULL) return NULL;
if (next_name_read>=nmtab_size) return NULL;
return nametable[next_name_read++].name;
}
int read_group(int index)
{
return grptable[index<<1];
}
char add_patch_file(char *filename)
{
long l;
long poc;
int i,cc=0;
TNAMETABLE p;
SEND_LOG("Adding patch: %s",filename,0);
if (patch!=-1) return 2;
if (bmf==-1) return 3;
patch=open(filename,O_BINARY|O_RDONLY);
if (patch==-1) return 1;
lseek(patch,4,SEEK_SET);
read(patch,&l,4);
lseek(patch,l,SEEK_SET);
read(patch,&p,sizeof(p));
poc=(p.seek-l)/sizeof(p);
lseek(patch,l,SEEK_SET);
for(i=0;i<poc;i++)
{
int j;
read(patch,&p,sizeof(p));
j=find_name(read_group(0),p.name);
if (j==-1)
{
nametable=grealloc(nametable,sizeof(TNAMETABLE)*(nmtab_size+1));
j=nmtab_size++;strncpy(nametable[j].name,p.name,12);
}
nametable[j].seek=-p.seek,cc++;
}
SEND_LOG("Patch added: %s - %d entries modified",filename,cc);
return 0;
}
#ifdef LOGFILE
/*
void free(void *c)
{
if (c==NULL) return;
SEND_LOG("(ALLOC)úúú Dealloc: %p size %d",c,*((long *)c-1));
free(c);
}
*/
/*
int get_time_macro();
#pragma aux get_time_macro parm[]=\
"mov ah,02"\
"int 1ah"\
"mov al,dh"\
"shl eax,16"\
"mov ax,cx"\
modify[eax ecx edx ebx esi edi]
char get_bcd(char bcd);
#pragma aux get_bcd parm[al]=\
"mov bl,al"\
"shr al,4"\
"mov ah,10"\
"mul ah"\
"and bl,0fh"\
"add al,bl"\
value[al] modify [eax ebx]
*/
char *get_time_str()
{
time_t long_time;
struct tm *newtime;
static char text[20];
time( &long_time ); /* Get time as long integer. */
newtime = localtime( &long_time ); /* Convert to local time. */
sprintf(text,"%02d:%02d:%02d",newtime->tm_hour,newtime->tm_min,newtime->tm_sec);
return text;
}
#endif
long get_handle_size(int handle)
{
THANDLE_DATA *h;
h=get_handle(handle);
if (h->status==BK_NOT_USED) return -1;
return h->size;
}
/*void *malloc(size_t size)
{
static char zavora=1;
void *c;
c=_nmalloc(size);
if (log!=NULL && zavora)
{
zavora=0;
fprintf(log,"Alloc: %p size %d\n",c,*((long *)c-1));
zavora=1;
}
return c;
}
*/
FILE *afiletemp(char *filename, int group)
{
long size;
void *p=afile(filename,group,&size);
FILE *f;
if (p==NULL) return NULL;
f=tmpfile();
if (f==NULL) {free(p);return NULL;}
fwrite(p,size,1,f);
fseek(f,0,SEEK_SET);
return f;
}

121
libs/memman.h Normal file
View file

@ -0,0 +1,121 @@
//#define LOGFILE
#include <stdio.h>
#ifndef _MEMMAN_H_
#define _MEMMAN_H_
#define freemem(size) free(size);
//#define malloc(size) getmem(size)
#define New(typ) (typ *)getmem(sizeof(typ))
#define NewArr(typ,count) (typ *)getmem(sizeof(typ)*(count))
typedef struct meminfo {
unsigned LargestBlockAvail;
unsigned MaxUnlockedPage;
unsigned LargestLockablePage;
unsigned LinAddrSpace;
unsigned NumFreePagesAvail;
unsigned NumPhysicalPagesFree;
unsigned TotalPhysicalPages;
unsigned FreeLinAddrSpace;
unsigned SizeOfPageFile;
unsigned Reserved[3];
} MEMINFO;
typedef struct thandle_data
{
char src_file[12]; //12
long seekpos; //16
void *blockdata; //20
char flags; //21
char path; //22
short status;
void (*loadproc)(void **data,long *size);//28
unsigned short lockcount; //32
unsigned long counter;
unsigned long size;
}THANDLE_DATA;
#define BK_MAJOR_HANDLES 256 // maximalni pocet skupin rukojeti
#define BK_MINOR_HANDLES 256 // pocet rukojeti v jedne skupine
typedef THANDLE_DATA handle_list[BK_MINOR_HANDLES];
typedef handle_list *handle_groups[BK_MAJOR_HANDLES];
//status
#define BK_NOT_USED 0
#define BK_NOT_LOADED 1
#define BK_PRESENT 2
#define BK_SWAPED 3
#define BK_DIRLIST 4 //znaci ze handle je docasne pouzito pro adresarovy list
//pokud je status=4 je automaticky chapan jako 1.
#define BK_SAME_AS 5
//flags
#define BK_LOCKED 1
#define BK_SWAPABLE 2
#define BK_SHARED 4
#define BK_PRELOAD 8
#define BK_HSWAP 16
extern char **mman_pathlist; //tento pointer musi byt naplnen ukazatelem na tabulku cest
extern void (*mem_error)(size_t); //pokud neni NULL je tato funkce volana vzdy kdyz dojde pamet a system si s tim nevi rady
extern void (*swap_error)();
extern int memman_handle; //cislo handle naposled zpracovavaneho prikazem ablock
extern char mman_patch; //jednicka zapina moznost pouziti patchu
void *getmem(long size); //alokace pameti pres memman. alokovat pomoci malloc lze ale hrozi nebezpeci ze vrati NULL
void *grealloc(void *m,long size); //realokace pameti pres memman
void *load_file(char *filename); //obycejne natahne soubor do pameti a vrati ukazatel.
void init_manager(char *filename,char *swp); //inicializuje manager. Jmeno filename i swapname nejsou povinne (musi byt NULL kdyz nejsou pouzity)
THANDLE_DATA *def_handle(int handle,char *filename,void *decompress,char path); //deklaruje rukojet. promenna decompress je ukazatel na funkci ktera upravi data pred vracenim ukazatele
void *ablock(int handle); //vraci ukazatel bloku spojeneho s handlem
void alock(int handle); //zamyka blok
void aunlock(int handle); //odmyka blok
void aswap(int handle); //zapina swapovani pro blok
void aunswap(int handle); //vypina swapovani pro blok
void apreload(int handle); //zapina preloading pro blok (preloading proved pomoci ablock)
//void free(); //free
void close_manager(); //uzavre manager a uvolni veskerou pamet
void undef_handle(int handle); //uvolni hadle k dalsimu pouziti
THANDLE_DATA *zneplatnit_block(int handle); //zneplatni data bloku
THANDLE_DATA *get_handle(int handle); //vraci informace o rukojeti
int find_handle(char *name,void *decomp); //hleda mezi rukojeti stejnou definici
int test_file_exist(int group,char *filename); //testuje zda soubor existuje v ramci mmanageru
void *afile(char *filename,int group,long *blocksize); //nahraje do pameti soubor registrovany v ramci mmanageru
long get_handle_size(int handle);
//void get_mem_info(MEMORYSTATUS *mem);
void apreload_sign(int handle,int max_handle); //pripravi preloading pro nacteni dat z CD (sekvencne)
void apreload_start(void (*percent)(int cur,int max)); //provede sekvenci apreload
char *read_next_entry(char mode); //cte adresar DDL souboru a vraci jmeno, nebo NULL. mode udava, zda se hleda od zacatku, nebo pokracuje tam kde program skoncil
int read_group(int index);
char add_patch_file(char *filename); //pripojuje zaplatu
FILE *afiletemp(char *filename, int group);
#define MMA_READ 1
#define MMA_SWAP 2
#define MMA_SWAP_READ 3
#define MMA_FREE 4
#define MMR_FIRST 0
#define MMR_NEXT 1
extern void (*mman_action)(int action); //udalost volajici se pri akci mmanagera.
void display_status(); //zobrazi na display status memmanageru
#ifdef LOGFILE
char *get_time_str();
int q_current_task();
#define OPEN_LOG(log) memcpy(stderr,fopen(log,"w"),sizeof(FILE));
#define SEND_LOG(format,parm1,parm2) fprintf(stderr,"%-2d %s "format"\n",q_current_task(),get_time_str(),parm1,parm2),fflush(stderr)
#define CLOSE_LOG() fclose(logfile);
#else
#define OPEN_LOG(log)
#define SEND_LOG(format,parm1,parm2)
#define CLOSE_LOG()
#endif
#endif

384
libs/mgfplay.c Normal file
View file

@ -0,0 +1,384 @@
#include <skeldal_win.h>
// MOTION GIF - LZW komprimovana animace v rozliseni 320x180 256 barev avsak
// upravena pro prehravani v HICOLOR pro konkretni rezim (32768 barev)
// Format
/*
[ FRAME ] <pocet_chunku 1b><delka frame 3b>
[CHUNK] <cislo_akce 1b><delka_chunku 3b> !pozor delka je 3 bajtova (tj 16MB)
0 - PRADNY CHUNK
1 - LZW FULL SCREEN
2 - MGIF DELTA
3 - HICOLOR PALETE
4 - SOUND TRACK
5 - TEXT TRACK
6 - MGIF COPY
7 - SOUND INIT
Popis Chunku:
PRAZDNY_CHUNK - muze obsahovat soukrome informace
LZW_FULL_SCREEN
- ihned za hlavickou nasleduje LZW komprimovany obrazek
v rozliseni 320x180 256 barev
MGIF_DELTA
- cely blok je LZW komprimovany. Po dekomprimace blok obsahuje
dva druhy informaci. Prvni DWORD je ofset od pocatku dat
ktery ukazuje na zacatek graficke informace. Po tomto
DWORDU jsou ulozeny data o umisteni grafickych bodu v obrazu
Prvni byte znaci, kolik je nutne preskocit slov. (tj *2 byte)
Dalsi byte znaci, kolik je nutne zapsat slov (tj *2 byte)
Po tomto bytu je nutne prenest presne tolik slov z
grafickeho bloku na obrazovku. Dvojice bajtu se opakuji
dokud ani jeden z nich nema nejvyssi 2 bity nastavene.
Pak tento byte znaci ze uz na radce nic vic neni. Dolni cast
byte (tj 6 bitu) pak udava pocet radku, ktere je treba pre-
skocit. (nula=zadny).
HICOLOR PALETTE
- Prvni byte znamena pocet aktivnich barev. Pak nasleduje
paleta ve formatu xRRRRRGGGGGBBBBB. Rozdil oproti vsem
beznym paletam je v tom ze neni treba v palete udrzovat
barvy, ktere uz na obrazovce jsou, protoze zmena palety
se neprojevi na jiz zobrazenem obrazku.
SOUND_TRACK
- Kazdy frame obsahuje zvukovou stopu. Je to RAW format.
Pro verzi MGIF97 zde je zvukova informace ulozena ve
zvukove kvalite 16-bit stereo 22000Khz, ovsem komprimovana
na 50% jako MUS.
TEXT_TRACK
- Navic je ve mozne ve frame umistit textovou zpravu (titulek)
Prvni WORD udava dobu zobrazeni (pocet frame).
Pote nasleduje text zakoncen znakem 0;
MGIF_COPY - Za timto CHUNKEM je ulozen blok dat v nezakomprimovanem
tvaru(tj 57600byte);
*/
#include <stdio.h>
#include <stdlib.h>
#include <types.h>
#include <bgraph.h>
#include <memman.h>
#include <mem.h>
#include <zvuk.h>
#include <bios.h>
//#include <vesa.h>
//#include <i86.h>
#include <io.h>
#include <mgifmem.h>
#include <strlite.h>
//#include <sys\types.h>
//#include <sys\stat.h>
#include <fcntl.h>
#include "lzwc.h"
static char konec=0;
static char sound_enabled=0;
static char **titles=NULL;
static int titlesize;
static word *scrbuff=NULL;
static char redraw=0;
static char bankmode=0;
static char colr64=0;
static void *bufpos;
long vals_save=0x80008000;
static void *f,*temp;
static int posyb,posyl;
static int posy2b,posy2l;
static int posyc;
static char full_mode=0;
static char *load_buffer;
static int buf_size;
static int buf_pos;
static char screen_mode=SMD_256;
/*typedef struct mgif_header
{
char sign[4];
char year[2];
char eof;
word ver;
long frames;
word snd_chans;
int snd_freq;
short ampl_table[256];
short reserved[32];
};
*/
static struct mgif_header gh;
static int mgf;
static int chunks;
static word hipal[256];
static void bread(void *what,int size)
{
register remain=buf_size-buf_pos;
register readed;
do
{
readed=size;
if (readed>remain) readed=remain;
if (readed)memcpy(what,buf_pos+load_buffer,readed);
size-=readed;
remain-=readed;
what=(char *)what+readed;
buf_pos+=readed;
if (!remain)
{
read(mgf,load_buffer,buf_size);
buf_pos=0;
remain=buf_size;
}
}
while (size);
}
static char open_mgf_file(char *filename)
{
mgf=open(filename,O_BINARY | O_RDONLY);
if (mgf==-1) return 1;
bread(&gh,sizeof(gh));
vals_save=0;
bufpos=NULL;
return 0;
}
static void close_mgf_file()
{
close(mgf);
}
static void load_frame(void *f)
{
long frame_head;
long frame_size;
bread(&frame_head,4);
chunks=frame_head & 0xff;
frame_size=frame_head>>8;
bread(f,frame_size);
}
static void load_lzw_frame(void *p,void *temp)
{
reinit_lzw();
lzw_decode(p,temp);
}
void show_full_interl_lfb(void *source,void *target,void *palette);
//#pragma aux show_full_interl_lfb parm [esi][edi][ebx] modify [eax ecx edx]
void show_delta_interl_lfb(void *source,void *target,void *palette);
//#pragma aux show_delta_interl_lfb parm [esi][edi][ebx] modify [eax ecx edx]
void show_full_interl_bank(void *source,void *target,void *palette);
//#pragma aux show_full_interl_bank parm [esi][edi][ebx] modify [eax ecx edx]
void show_delta_interl_bank(void *source,void *target,void *palette);
//#pragma aux show_delta_interl_bank parm [esi][edi][ebx] modify [eax ecx edx]
void *sound_decompress(void *source,void *bufpos,int size,void *ampl_tab);
//#pragma aux sound_decompress parm [esi][edi][ecx][ebx] modify [eax edx] value [edi]
char test_next_frame(void *bufpos,int size);
//#pragma aux test_next_frame parm [edi][ecx] modify [ebx] value [al]
void show_full_interl_lfb_256(void *source,void *target,void *palette);
//#pragma aux show_full_interl_lfb_256 parm [esi][edi][ebx] modify [eax ecx edx]
void show_delta_interl_lfb_256(void *source,void *target,void *palette);
//#pragma aux show_delta_interl_lfb_256 parm [esi][edi][ebx] modify [eax ecx edx]
static void conv_palette_256(word *pal)
{
register i;
for(i=0;i<256;i++,pal++)
{
*pal=*((word *)xlatmem+(*pal & 0x7fff));
}
}
#define SWAP(a,b) a^=b,b^=a,a^=b
static void show_title(int frame)
{
int y,yt,h;
static int lasty;
char *c;
if (frame==0) lasty=478;
if (titlesize<=frame) return;
if (titles[frame]==NULL) return;
h=text_height(titles[frame])+2;
yt=y=479-2*h;
curcolor=0;
bar(0,lasty,639,479);
c=strchr(titles[frame],'\n');
if (c!=NULL) *c=0;
set_aligned_position(320,y,1,0,titles[frame]);
outtext(titles[frame]);
if (c!=NULL)
{
*c='\n';c++;y+=h;
set_aligned_position(320,y,1,0,c);
outtext(c);
}
if (lasty<yt) y=lasty;else y=yt;
showview(0,y,640,480-y);
lasty=yt;
}
static char waited=0;
static void show_frame(void *fr,void *temp)
{
int x;
char *p,a;
long siz;
int frmode=0,i;
void *sound=NULL;int ssize;
static last_counter=-1;
int minspeed;
p=fr;
for(x=0;x<chunks;x++)
{
a=*p;siz=*(long *)p>>8;p+=4;
switch(a)
{
case MGIF_LZW:
case MGIF_DELTA:load_lzw_frame(p,temp);frmode=a;break;
case MGIF_PAL:memcpy(hipal,p,siz);break;
case MGIF_COPY:temp=p;frmode=a;break;
case MGIF_SOUND:sound=p;ssize=siz;break;
}
p+=siz;
}
if (sound!=NULL)
{
waited=0;
if (sound_enabled)
{
while (test_next_frame(bufpos,ssize)) waited=1;
bufpos=sound_decompress(sound,bufpos,ssize,&gh.ampl_table);
}
else
{
if (last_counter==-1) last_counter=get_timer_value();
minspeed=(ssize*50+22050)/44100;
while (get_timer_value()-last_counter<minspeed) waited=1;;
last_counter=get_timer_value();
}
}
else Sleep(50);
for(i=0;i<=full_mode;i++)
{
switch (frmode)
{
case MGIF_LZW:
case MGIF_COPY:show_full_interl_lfb(temp,scrbuff+posyl,hipal);break;
case MGIF_DELTA:show_delta_interl_lfb(temp,scrbuff+posyl,hipal);break;
}
}
if (redraw && waited) showview(0,posyc,640,360);
}
//extern int test_counter;
static void play_frames()
{
int x;
for(x=0;x<gh.frames;x++)
{
load_frame(f);
show_frame(f,temp);
if (titles!=NULL) show_title(x);
if (_bios_keybrd(_KEYBRD_READY))
{
konec=1;
break;
}
}
}
static void init_mgif_player(int posy)
{
fade_music();
f=getmem(65536);
temp=getmem(65536);
posyb=scr_linelen*posy;posy2b=posyb+1280;
posyl=scr_linelen2*posy;posy2l=posyl+scr_linelen2;
curcolor=0;
bar(0,posy,639,posy+360);showview(0,posy,640,360);
posyc=posy;
set_backsnd_freq(22050);
}
static void done_mgif_player()
{
free(f);
free(temp);
mix_back_sound(3);
change_music("?");
}
static void init_load_buffer(int size)
{
load_buffer=getmem(buf_size=size);
buf_pos=buf_size;
}
static void done_load_buffer()
{
free(load_buffer);
}
void play_animation(char *filename,char mode,int posy,char sound)
{
word *lbuffer=GetScreenAdr();
if (scrbuff==NULL) scrbuff=lbuffer;
screen_mode=mode & 0x7f;
full_mode=mode>>7;
sound_enabled=sound;
init_load_buffer(64*1024);
init_mgif_player(posy);
init_lzw_compressor(8);
if (!open_mgf_file(filename))
{
play_frames();
close_mgf_file();
}
done_lzw_compressor();
done_mgif_player();
done_load_buffer();
}
void set_title_list(char **title_list)
{
titles=title_list;
if (titles!=NULL)titlesize=str_count(titles);else titlesize=0;
}
void set_play_attribs(void *screen,char rdraw,char bm,char col64)
{
scrbuff=screen;
redraw=rdraw;
bankmode=bm;
colr64=col64;
}

7
libs/mgfplay.h Normal file
View file

@ -0,0 +1,7 @@
#define SMD_256 1
#define SMD_HICOLOR 2
#define SMD_256_FULL (1+128)
#define SMD_HICOLOR_FULL (2+128)
void play_animation(char *filename,char mode,int posy,char sound);
void set_title_list(char **titles);
void set_play_attribs(void *screen,char rdraw,char bm,char colr64);

147
libs/mgifmapmem.c Normal file
View file

@ -0,0 +1,147 @@
#include <skeldal_win.h>
#include <bgraph.h>
#include <bgraph2dx.h>
#include <stdio.h>
#include "types.h"
#include "memman.h"
#include "mem.h"
#include "mgifmem.h"
#include <zvuk.h>
static HANDLE mapped_mgif;
static HANDLE mgif_file;
static MGIF_HEADER_T *mgif_header;
static short mgif_accnums[2];
static long mgif_writepos;
static void *OpenMGFFile(const char *filename)
{
mgif_file=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (mgif_file==INVALID_HANDLE_VALUE) return NULL;
mapped_mgif=CreateFileMapping(mgif_file,NULL,PAGE_READONLY,0,0,NULL);
if (mapped_mgif==INVALID_HANDLE_VALUE) return NULL;
return MapViewOfFile(mapped_mgif,FILE_MAP_READ,0,0,0);
}
static word *paleta;
static word *picture;
static word *anim_render_buffer;
static void *sound;
static void StretchImageHQ(word *src, word *trg, unsigned long linelen, char full)
{
word xs=src[0],ys=src[1];
word *s,*t;
int x,y;
src+=3;
for (y=0,s=src,t=trg;y<ys;y++,t+=linelen*2,s+=xs)
for (x=0;x<xs;x++)
{
word val;
t[x*2]=s[x]+(s[x]&0x7fe0);
if (x)
{
val=((s[x-1] & 0x7bde)+(s[x] & 0x7bde))>>1;
t[x*2-1]=val+(val&0x7fe0);
}
if (full)
{
if (y)
{
val=((s[x-xs] & 0x7bde)+(s[x] & 0x7bde))>>1;
t[x*2-linelen]=val+(val&0x7fe0);
}
if (x && y)
{
val=((s[x-xs-1] & 0x7bde)+(s[x] & 0x7bde))>>1;
t[x*2-linelen-1]=val+(val&0x7fe0);
}
}
}
}
static void PlayMGFFile(void *file, MGIF_PROC proc,int ypos,char full)
{
mgif_install_proc(proc);
sound=PrepareVideoSound(22050,256*1024);
mgif_accnums[0]=mgif_accnums[1]=0;
mgif_writepos=65536;
picture=getmem(2*3+320*180*2);
picture[0]=320;
picture[1]=180;
picture[2]=15;
memset(picture+3,0,320*180*2);
anim_render_buffer=picture+3;
mgif_header=(MGIF_HEADER_T *)file;
file=open_mgif(file);
if (file==NULL) return;
while (file)
{
__try
{
file=mgif_play(file);
}
__except(1)
{
SEND_LOG("(PLAYANIM) Exception raised",0,0);
file=NULL;
}
StretchImageHQ(picture, GetScreenAdr()+ypos*scr_linelen2, scr_linelen2,full);
showview(0,ypos,0,360);
if (_bios_keybrd(_KEYBRD_READY)==0) mix_back_sound(0);
else
{
_bios_keybrd(_KEYBRD_READ);
break;
}
}
close_mgif();
DoneVideoSound(sound);
free(picture);
}
static void CloseMGFFile(void *file)
{
UnmapViewOfFile(file);
CloseHandle(mapped_mgif);
CloseHandle(mgif_file);
}
void show_full_lfb12e(void *target,void *buff,void *paleta);
void show_delta_lfb12e(void *target,void *buff,void *paleta);
void show_delta_lfb12e_dx(void *target,void *buff,void *paleta);
void show_full_lfb12e_dx(void *target,void *buff,void *paleta);
void BigPlayProc(int act,void *data,int csize)
{
switch (act)
{
case MGIF_LZW:
case MGIF_COPY:show_full_lfb12e(anim_render_buffer,data,paleta);break;
case MGIF_DELTA:show_delta_lfb12e(anim_render_buffer,data,paleta);break;
case MGIF_PAL:paleta=data;break;
case MGIF_SOUND:
while (LoadNextVideoFrame(sound,data,csize,mgif_header->ampl_table,mgif_accnums,&mgif_writepos)==0);
}
}
void play_animation(char *filename,char mode,int posy,char sound)
{
void *mgf=OpenMGFFile(filename);
change_music(NULL);
if (mgf==NULL) return;
PlayMGFFile(mgf,BigPlayProc,posy,mode & 0x80);
CloseMGFFile(mgf);
}
void set_title_list(char **titles)
{
}
void set_play_attribs(void *screen,char rdraw,char bm,char colr64)
{
}

3
libs/mgifmapmem.h Normal file
View file

@ -0,0 +1,3 @@
void play_animation(char *filename,char mode,int posy,char sound);
void set_title_list(char **titles);
void set_play_attribs(void *screen,char rdraw,char bm,char colr64);

275
libs/mgifmem.c Normal file
View file

@ -0,0 +1,275 @@
#include <skeldal_win.h>
#include <stdio.h>
#include "types.h"
#include "memman.h"
#include "mem.h"
#include "mgifmem.h"
#define MGIF "MGIF"
#define LZW_MAX_CODES 16384
#define LZW_BUFFER 64000
MGIF_PROC show_proc;
static int mgif_frames;
static int cur_frame;
typedef struct double_s
{
short group,chr,first,next;
}DOUBLE_S;
typedef DOUBLE_S CODE_TABLE[LZW_MAX_CODES];
DOUBLE_S *compress_dic=NULL;
static void *lzw_buffer=NULL;
static int clear_code;
static int end_code;
static int free_code;
static int nextgroup;
static int bitsize,init_bitsize;
char old_value=0;
void do_clear_code()
{
int i;
old_value=0;
nextgroup=free_code;
bitsize=init_bitsize;
for(i=0;i<clear_code;i++)
{
DOUBLE_S *p;
p=&compress_dic[i];
p->group=i;p->chr=-1;p->next=-1;p->first=-1;
}
}
void reinit_lzw()
{
do_clear_code();
}
void init_lzw_compressor(int dic_size)
{
if (compress_dic==NULL) compress_dic=(DOUBLE_S *)getmem(sizeof(CODE_TABLE));
clear_code=1<<dic_size;
end_code=clear_code+1;
free_code=end_code+1;
nextgroup=free_code;
init_bitsize=bitsize=dic_size+1;
do_clear_code();
}
void done_lzw_compressor()
{
free(compress_dic);
compress_dic=NULL;
}
void mgif_install_proc(MGIF_PROC proc)
{
show_proc=proc;
}
void *open_mgif(void *mgif) //vraci ukazatel na prvni frame
{
char *c;
struct mgif_header *mgh;
c=mgif;
if (strncmp(c,MGIF,4)) return NULL;
mgh=mgif;
mgif_frames=mgh->frames;
cur_frame=0;
c+=sizeof(*mgh);
init_lzw_compressor(8);
if (lzw_buffer==NULL) lzw_buffer=getmem(LZW_BUFFER);
return c;
}
void close_mgif() //dealokuje buffery pro prehravani
{
done_lzw_compressor();
free(lzw_buffer);
lzw_buffer=NULL;
}
int input_code(void *source,long *bitepos,int bitsize,int mask)
{
__asm
{
mov esi,source
mov edi,bitepos
mov ebx,bitsize
mov edx,mask
mov ecx,[edi]
mov eax,ecx
shr eax,3
mov eax,[esi+eax]
and cl,7
shr eax,cl
and eax,edx
add [edi],ebx
}
}
//#pragma aux input_code parm [esi][edi][ebx][edx]=\ value[eax] modify [ecx];
int de_add_code(int group,int chr,int mask)
{
DOUBLE_S *q;
q=&compress_dic[nextgroup];q->group=group;q->chr=chr;q->first=compress_dic[group].first+1;
nextgroup++;
if (nextgroup==mask)
{
mask=(mask<<1)+1;
bitsize++;
}
return mask;
}
char fast_expand_code(int code,char **target)
//#pragma aux fast_expand_code parm[eax][edi] modify [esi ecx] value [bl]
{
_asm
{
mov eax,code
mov edi,target
cmp eax,256
jnc expand
mov esi,[edi]
inc dword ptr [edi]
mov bl,al
add al,old_value
mov [esi],al
mov old_value,al
jmp end
expand:
mov ebx,compress_dic
lea ecx,[eax*8+ebx]
movzx eax,short ptr [ecx+4]
add [edi],eax
push eax
mov esi,[edi]
eloop:movzx eax,short ptr [ecx+2]
mov [esi],al
dec esi
movzx eax,short ptr [ecx]
lea ecx,[eax*8+ebx]
cmp eax,256
jnc eloop
mov bl,al
add al,old_value
mov [esi],al
inc dword ptr [edi]
pop ecx
elp2:inc esi
add al,[esi]
mov [esi],al
dec ecx
jnz elp2
mov old_value,al
end:
movzx eax,bl
}
}
void lzw_decode(void *source,char *target)
{
long bitpos=0;
register int code;
int old,i;
//int group,chr;
int old_first;
register int mask=0xff;
for(i=0;i<LZW_MAX_CODES;i++) compress_dic[i].first=0;
clear:
old_value=0;
nextgroup=free_code;
bitsize=init_bitsize;
mask=(1<<bitsize)-1;
code=input_code(source,&bitpos,bitsize,mask);
old_first=fast_expand_code(code,&target);
old=code;
while ((code=input_code(source,&bitpos,bitsize,mask))!=end_code)
{
if (code==clear_code)
{
goto clear;
}
else if (code<nextgroup)
{
old_first=fast_expand_code(code,&target);
//group=old;
//chr=old_first;
mask=de_add_code(old,old_first,mask);
old=code;
}
else
{
//p.group=old;
//p.chr=old_first;
mask=de_add_code(old,old_first,mask);
old_first=fast_expand_code(code,&target);
old=code;
}
}
}
void *mgif_play(void *mgif) //dekoduje a zobrazi frame
{
char *pf,*pc,*ff;
int acts,size,act,csize;
void *scr_sav;
int scr_act=-1;
pf=mgif;
acts=*pf++;
size=(*(int *)pf) & 0xffffff;
pf+=3;pc=pf;pf+=size;
if (acts)
do
{
act=*pc++;csize=(*(int *)pc) & 0xffffff;pc+=3;
if (act==MGIF_LZW || act==MGIF_DELTA)
{
ff=lzw_buffer;
lzw_decode(pc,ff);
scr_sav=ff;
scr_act=act;
}
else if (act==MGIF_COPY)
{
scr_sav=ff;scr_act=act;
}
else
{
ff=pc;
show_proc(act,ff,csize);
}
pc+=csize;
}
while (--acts);
if (scr_act!=-1) show_proc(scr_act,scr_sav,csize);
cur_frame+=1;
if (cur_frame==mgif_frames) return NULL;
return pf;
}

40
libs/mgifmem.h Normal file
View file

@ -0,0 +1,40 @@
//!!!! POZOR, NUTNE LINKOVAT SOUBOR LZWA.ASM
#ifndef _MGIFMEM_H
typedef void (*MGIF_PROC)(int,void *,int csize); //prvni cislo akce, druhy data akce
#define _MGIFMEM_H
#define MGIF "MGIF"
#define MGIF_Y "97"
#define VER 0x100
#define MGIF_EMPTY 0
#define MGIF_LZW 1
#define MGIF_DELTA 2
#define MGIF_PAL 3
#define MGIF_SOUND 4
#define MGIF_TEXT 5
#define MGIF_COPY 6
#define MGIF_SINIT 7
#define SMD_256 1
#define SMD_HICOLOR 2
typedef struct mgif_header
{
char sign[4];
char year[2];
char eof;
word ver;
long frames;
word snd_chans;
int snd_freq;
short ampl_table[256];
short reserved[32];
}MGIF_HEADER_T;
void mgif_install_proc(MGIF_PROC proc);
void *open_mgif(void *mgif); //vraci ukazatel na prvni frame
void *mgif_play(void *mgif); //dekoduje a zobrazi frame
void close_mgif(); //dealokuje buffery pro prehravani
#endif

302
libs/mgifplaya.c Normal file
View file

@ -0,0 +1,302 @@
#include <skeldal_win.h>
#include "types.h"
#include <mgfplay.h>
#include <bgraph.h>
void show_full_interl_lfb(void *source,void *target,void *palette, long linelen)
{
int sslinelen=2*linelen-1280;
__asm
{
mov edi,target
mov esi,source
mov ebx,palette
;edi - target
;esi - source
;ebx - palette
push ebp
push sslinelen;
mov dl,180
shfif2: mov ecx,320
shfif1: lodsb
movzx eax,al
movzx eax,short ptr [eax*2+ebx]
mov ebp,eax
shl eax,16
or eax,ebp
stosd
dec ecx
jnz shfif1
add edi,[esp]
dec dl
jnz shfif2
pop eax
pop ebp
}
}
//#pragma aux show_full_interl_lfb parm [esi][edi][ebx] modify [eax ecx edx]
void show_delta_interl_lfb(void *source,void *target,void *palette, long linelen)
{
int sslinelen=2*linelen;
__asm
{
mov edi,target
mov esi,source
mov ebx,palette
;edi - target
;esi - source
;ebx - palette
push ebp ;uchovej ebp
push sslinelen
mov cl,180 ;cl pocet zbyvajicich radek
add esi,4 ;preskoc ukazatel
mov edx,esi ;edx - zacatek delta mapy
add esi,[esi-4] ;esi - zacatek dat
shdif6: push edi ;uloz adresu radku
shdif2: mov ch,[edx] ;cti _skip_ hodnotu
mov al,ch
inc edx
or al,03fh ;test zda jsou 2 nejvyssi bity nastaveny
inc al
jz shdif3 ;ano - preskakovani radku
movzx eax,ch ;expanduj _skip_ hodnotu do eax
lea edi,[eax*8+edi] ;vypocti novou pozici na obrazovce
mov ch,[edx] ;cti _copy_ hodnotu
inc edx
shdif1: lodsb ;vem bajt z datove oblasti
movzx eax,al ;expanduj do eax
movzx eax,short ptr[eax*2+ebx] ;expanduj hicolor barvu
mov ebp,eax ;rozdvoj barvy
shl ebp,16
or eax,ebp
stosd ;zapis dva body
lodsb ;opakuj pro dalsi bod jeste jednou
movzx eax,al
movzx eax,short ptr[eax*2+ebx]
mov ebp,eax
shl ebp,16
or eax,ebp
stosd
dec ch ;odecti _copy_ hodnotu
jnz shdif1 ;dokud neni 0
jmp shdif2 ;pokracuj _skip_ hodnotou
shdif3: and ch,3fh ;odmaskuj hodni 2 bity
pop edi ;obnov edi
jnz shdif4 ;pokud je ch=0 preskoc jen jeden radek;
add edi,[esp] ;preskoc radek
dec cl ;odecti citac radku
jnz shdif6 ;skok pokud neni konec
pop ebp
jmp konec ;navrat
shdif4: inc ch ;pocet radek je ch+1
sub cl,ch ;odecti ch od zbyvajicich radek
jz shdif5 ;je-li nula tak konec
shdif7: add edi,[esp] ;preskoc radek
dec ch ;odecti ch
jnz shdif7 ;preskakuj dokud neni 0
jmp shdif6 ;cti dalsi _skip_
shdif5: pop ebp
konec:
}
}
//#pragma aux show_delta_interl_lfb parm [esi][edi][ebx] modify [eax ecx edx]
void show_full_lfb12e(void *target,void *buff,void *paleta)
{
__asm
{
mov edi,target
mov esi,buff
mov ebx,paleta
;edi - target
;esi - source
;ebx - palette
push ebp
mov dl,180
shfl2: mov ecx,160
shfl1: lodsw
movzx ebp,al
movzx ebp,short ptr ds:[ebp*2+ebx]
movzx eax,ah
movzx eax,short ptr ds:[eax*2+ebx]
shl eax,16
or eax,ebp
stosd
dec ecx
jnz shfl1
dec dl
jnz shfl2
pop ebp
}
}
//#pragma aux show_full_lfb12e parm[edi][esi][ebx] modify [eax ecx]
void show_delta_lfb12e(void *target,void *buff,void *paleta)
{
__asm
{
mov edi,target
mov esi,buff
mov ebx,paleta
;edi - target
;esi - buff
;ebx - paleta
push ebp ;uchovej ebp
mov cl,180 ;cl pocet zbyvajicich radek
add esi,4 ;preskoc ukazatel
mov edx,esi ;edx - zacatek delta mapy
add esi,[esi-4] ;esi - zacatek dat
shdl6: push edi ;uloz adresu radku
shdl2: mov ch,[edx] ;cti _skip_ hodnotu
mov al,ch
inc edx
or al,03fh ;test zda jsou 2 nejvyssi bity nastaveny
inc al
jz shdl3 ;ano - preskakovani radku
movzx eax,ch ;expanduj _skip_ hodnotu do eax
lea edi,[eax*4+edi] ;vypocti novou pozici na obrazovce
mov ch,[edx] ;cti _copy_ hodnotu
inc edx
shdl1: lodsw
movzx ebp,al
movzx ebp,short ptr ds:[ebp*2+ebx]
movzx eax,ah
movzx eax,short ptr ds:[eax*2+ebx]
shl eax,16
or eax,ebp
stosd
dec ch ;odecti _copy_ hodnotu
jnz shdl1 ;dokud neni 0
jmp shdl2 ;pokracuj _skip_ hodnotou
shdl3: and ch,3fh ;odmaskuj hodni 2 bity
pop edi ;obnov edi
jnz shdl4 ;pokud je ch=0 preskoc jen jeden radek;
add edi,640 ;preskoc radek
dec cl ;odecti citac radku
jnz shdl6 ;skok pokud neni konec
pop ebp
jmp konec
shdl4: inc ch ;pocet radek je ch+1
sub cl,ch ;odecti ch od zbyvajicich radek
jz shdl5 ;je-li nula tak konec
shdl7: add edi,640 ;preskoc radek
dec ch ;odecti ch
jnz shdl7 ;preskakuj dokud neni 0
jmp shdl6 ;cti dalsi _skip_
shdl5: pop ebp
konec:
}
}
//#pragma aux show_delta_lfb12e parm[edi][esi][ebx] modify [eax ecx]
void show_full_lfb12e_dx(void *target,void *buff,void *paleta)
{
__asm
{
mov edi,target
mov esi,buff
mov ebx,paleta
;edi - target
;esi - source
;ebx - palette
push ebp
mov eax,scr_linelen
sub eax,640
push eax
mov dl,180
shfl2: mov ecx,160
shfl1: lodsw
movzx ebp,al
movzx ebp,short ptr ds:[ebp*2+ebx]
movzx eax,ah
movzx eax,short ptr ds:[eax*2+ebx]
shl eax,16
or eax,ebp
mov ebp,eax
and ebp,0x7fe07fe0
add eax,ebp
stosd
dec ecx
jnz shfl1
add edi,[esp]
dec dl
jnz shfl2
pop eax
pop ebp
}
}
//#pragma aux show_full_lfb12e parm[edi][esi][ebx] modify [eax ecx]
void show_delta_lfb12e_dx(void *target,void *buff,void *paleta,unsigned long Pitch)
{
__asm
{
mov edi,target
mov esi,buff
mov ebx,paleta
;edi - target
;esi - buff
;ebx - paleta
push ebp ;uchovej ebp
mov eax,scr_linelen
sub eax,640
push eax
mov cl,180 ;cl pocet zbyvajicich radek
add esi,4 ;preskoc ukazatel
mov edx,esi ;edx - zacatek delta mapy
add esi,[esi-4] ;esi - zacatek dat
shdl6: push edi ;uloz adresu radku
shdl2: mov ch,[edx] ;cti _skip_ hodnotu
mov al,ch
inc edx
or al,03fh ;test zda jsou 2 nejvyssi bity nastaveny
inc al
jz shdl3 ;ano - preskakovani radku
movzx eax,ch ;expanduj _skip_ hodnotu do eax
lea edi,[eax*4+edi] ;vypocti novou pozici na obrazovce
mov ch,[edx] ;cti _copy_ hodnotu
inc edx
shdl1: lodsw
movzx ebp,al
movzx ebp,short ptr ds:[ebp*2+ebx]
movzx eax,ah
movzx eax,short ptr ds:[eax*2+ebx]
shl eax,16
or eax,ebp
mov ebp,eax
and ebp,0x7fe07fe0
add eax,ebp
stosd
dec ch ;odecti _copy_ hodnotu
jnz shdl1 ;dokud neni 0
jmp shdl2 ;pokracuj _skip_ hodnotou
shdl3: and ch,3fh ;odmaskuj hodni 2 bity
pop edi ;obnov edi
jnz shdl4 ;pokud je ch=0 preskoc jen jeden radek;
add edi,scr_linelen ;preskoc radek
dec cl ;odecti citac radku
jnz shdl6 ;skok pokud neni konec
jmp shdl5
shdl4: inc ch ;pocet radek je ch+1
sub cl,ch ;odecti ch od zbyvajicich radek
jz shdl5 ;je-li nula tak konec
shdl7: add edi,scr_linelen ;preskoc radek
dec ch ;odecti ch
jnz shdl7 ;preskakuj dokud neni 0
jmp shdl6 ;cti dalsi _skip_
shdl5: pop eax
pop ebp
}
}
char test_next_frame(void *bufpos,int size)
{
return 0;
}
//#pragma aux test_next_frame parm [edi][ecx] modify [ebx] value [al]
void *sound_decompress(void *source,void *bufpos,int size,void *ampl_tab)
{
return NULL;
}
//#pragma aux sound_decompress parm [esi][edi][ecx][ebx] modify [eax edx] value [edi]

165
libs/mouse.c Normal file
View file

@ -0,0 +1,165 @@
/*
MOUSE.C - The following program demonstrates how
to use the mouse interrupt (0x33) with DOS/4GW.
Compile and link: wcl386 /l=dos4g mouse
*/
#include <stdio.h>
#include <dos.h>
#include <i86.h>
/* Data touched at mouse callback time -- they are in a structure to
simplify calculating the size of the region to lock.
*/
struct callback_data
{
int mouse_event;
unsigned short mouse_code;
unsigned short mouse_bx;
unsigned short mouse_cx;
unsigned short mouse_dx;
signed short mouse_si;
signed short mouse_di;
} cbd = { 0 };
int lock_region (void *address, unsigned length)
{
union REGS regs;
unsigned linear;
/* Thanks to DOS/4GW's zero-based flat memory model, converting
a pointer of any type to a linear address is trivial.
*/
linear = (unsigned) address;
regs.w.ax = 0x600; /* DPMI Lock Linear Region */
regs.w.bx = (linear >> 16); /* Linear address in BX:CX */
regs.w.cx = (linear & 0xFFFF);
regs.w.si = (length >> 16); /* Length in SI:DI */
regs.w.di = (length & 0xFFFF);
int386 (0x31, &regs, &regs);
return (! regs.w.cflag); /* Return 0 if can't lock */
}
#pragma off (check_stack)
void _loadds far click_handler (int max, int mbx, int mcx, int mdx, int msi, int mdi)
{
#pragma aux click_handler parm [EAX] [EBX] [ECX] [EDX] [ESI] [EDI]
cbd.mouse_event = 1;
cbd.mouse_code = (unsigned short) max;
cbd.mouse_bx = (unsigned short) mbx;
cbd.mouse_cx = (unsigned short) mcx;
cbd.mouse_dx = (unsigned short) mdx;
cbd.mouse_si = (signed short) msi;
cbd.mouse_di = (signed short) mdi;
if (cbd.mouse_code & 8) cbd.right_button = 1;
}
void cbc_end (void) /* Dummy function so we can */
{ /* calculate size of code to lock */
} /* (cbc_end - click_handler) */
#pragma on (check_stack)
// void main (void)
{
struct SREGS sregs;
union REGS inregs, outregs;
int installed = 0;
int orig_mode = 0;
int far *ptr;
int (far *function_ptr)();
segread(&sregs);
/* get original video mode */
inregs.w.ax = 0x0f00;
int386 (0x10, &inregs, &outregs);
printf ("Current Mode = %u\n", orig_mode = outregs.h.al);
/* check for mouse driver */
inregs.w.ax = 0;
int386 (0x33, &inregs, &outregs);
if (installed = (outregs.w.ax == -1))
printf ("Mouse installed...\n");
else
printf ("Mouse NOT installed...\n");
if (installed)
{
/* lock callback code and data (essential under VMM!)
note that click_handler, although it does a far return and
is installed using a full 48-bit pointer, is really linked
into the flat model code segment -- so we can use a regular
(near) pointer in the lock_region() call.
*/
if ((! lock_region (&cbd, sizeof(cbd))) ||
(! lock_region ((void near *) click_handler,
(char *) cbc_end - (char near *) click_handler)))
{
printf ("locks failed\n");
exit (1);
}
/* goto graphics mode */
inregs.h.ah = 0x00;
inregs.h.al = 0x12;
int386 (0x10, &inregs, &outregs);
/* show mouse cursor */
inregs.w.ax = 0x1;
int386 (0x33, &inregs, &outregs);
/* set mouse cursor form */
inregs.w.ax = 0x9;
inregs.w.bx = 0x0;
inregs.w.cx = 0x0;
ptr = cursor;
inregs.x.edx = FP_OFF (ptr);
sregs.es = FP_SEG (ptr);
int386x (0x33, &inregs, &outregs, &sregs);
/* install click watcher */
inregs.w.ax = 0xC;
inregs.w.cx = 0x0002 + 0x0008;
function_ptr = click_handler;
inregs.x.edx = FP_OFF (function_ptr);
sregs.es = FP_SEG (function_ptr);
int386x (0x33, &inregs, &outregs, &sregs);
while (!cbd.right_button)
{
if (cbd.mouse_event)
{
printf ("Ev %04hxh BX %hu CX %hu DX %hu SI %hd DI %hd\n",
cbd.mouse_code, cbd.mouse_bx, cbd.mouse_cx, cbd.mouse_dx,
cbd.mouse_si, cbd.mouse_di);
cbd.mouse_event = 0;
}
}
}
/* check installation again (to clear watcher) */
inregs.w.ax = 0;
int386 (0x33, &inregs, &outregs);
if (outregs.w.ax == -1)
printf ("DONE : Mouse still installed...\n");
else
printf ("DONE : Mouse NOT installed...\n");
inregs.h.ah = 0x00;
inregs.h.al = orig_mode;
int386 (0x10, &inregs, &outregs);
}

424
libs/pady.c Normal file
View file

@ -0,0 +1,424 @@
//Toto je pokus programu pro sklonovani jmen.
//Umi vysklonovat jen jmena z rodu muzskeho zivotneho a zenskeho.
//vse v cisle jednotnem.
//Hodi se do ceskych her pro oslovovani hracu.
//Padovani probiha tak:
/*
Ke jmenu je treba znat rod: Muzsky/ Zensky
Pak podle rodu se hleda ve vzorech pro muzky nebo zesky rod:
Nejprve se porovnaji dva posledni znaky jmeno s mapou znaku u zkoumaneho
vzoru. Pokud tyto znaky souhlasi, muze byt jmeno vysklonovano.
Pri sklonovani se neprve z koncovky odebere urcity, nebo zadny pocet znaku.
Potom se pripadne upravi konverze dlouheho 'u' s krouzkem na 'o' "Kun"=>"kone".
Nasledne se pripoji koncovka a nakonec se provede kontrola na znak e pred
souhlaskou, ktere je nutne vypustit: Marek => Marka.
Pri sklonovani muzou ale vzniknout chybne dvojznakove spojeni: treba znak 'n'
s hackem a 'e'. Tyto dvojice jsou vyhledany a nahrazeny dvojici spravnou,
v nasem pripade 'n' a 'e' s hackem.
Ja jen doufam ze tyto upravy maj obecny charakter :-)
Da se prepokladat ze ve svete existuje plno jmen, ktere nelze takto sklonovat.
U nekterych ani neni jasny jak tato jmena sklonovat. Treba
Bredy, Bredyho, Bredymu, Bredy, Bredy, Bredym, Bredym - Co je to za vzor ???
Uz nemluvim o jmenach cizich.
*/
//Definice knihoven
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
typedef char TPAD[8];
//typ TPAD predstavuje koncovku pro jeden pad
typedef char TZNAKY[40];
//typ TZNAKY predstavuje mapu znaku se kterymi vzor pracuje.
//pokud je na prvnim miste znak '*' tak vzor pracuje se vsemy.
typedef struct vzor
{
TZNAKY znak1;
TZNAKY znak2;
char chrdel;
TPAD pady[7];
}TVZOR;
//struktura TVZOR popisuje sklonovani jednoho vzoru
//znak1 predstavuje mapu znaku pro jmeno v prvnim pade na predposledni pozici
// ... pokud znak neni v mape, nelze jmeno v tomto vzoru sklonovat
//znak2 je jako znak1 s tim ze se testuje znak na posledni pozici
//chrdel je pocet znaku, ktere musi byt odebrany pred pridanim pripony.
//navic pokud je chrdel=0 uplatnuje se konverze Kun -> kone a podobne.
//pady predstavuje jednotlive koncovky pro pady
// pokud je pad roven '-' znamena to ze tvar je schodny jako v 1. pade.
TVZOR zena=
{
"hkrdtnbflmpsvz",
"a o˘uŁy<EFBFBD>",
1,
"-","y","<EFBFBD>","u","o","<EFBFBD>","ou"
};
//Vzor pro zena
TVZOR natasa=
{
"c‡<EFBFBD>j¤©¨ź",
"a ",
1,
"-","i","<EFBFBD>","u","o","<EFBFBD>","ou"
};
//Vzor pro zena koncici mekkou souhlaskou a a
TVZOR ruze=
{
"c‡<EFBFBD>j¤©¨ź",
"eiˇo˘uŁ",
1,
"-","e","i","i","e","i","ˇ"
};
//Vzor pro ruze s mekkou koncovkou
TVZOR ruze2=
{
"dtn",
"<EFBFBD>",
1,
"-","e","i","i","e","i","ˇ"
};
//Vzor pro ruze s tvrdou koncovkou d,t,n s mekkou samohlaskou
TVZOR pisen=
{
"*",
"c‡<EFBFBD>j¤©¨źflmsx",
0,
"-","e","i","-","i","i","ˇ"
};
//vzor pisen
TVZOR kost=
{
"*",
"hkrdtnbpvz",
0,
"-","i","i","-","i","i","ˇ"
};
//vzor kost
TVZOR pan=
{
"*",
"rdtnbflmpsvz",
0,
"-","a","ovi","a","e","ovi","em"
};
//vzor pan standardni
TVZOR pan2=
{
"*",
"hk",
0,
"-","a","ovi","a","u","ovi","em"
};
//vzor pan pro specialni koncovky h nebo k => pro 5. pad
// Rumburak => Rumburaku / nikoliv Rumburake.
TVZOR quasimodo=
{
"hkrdtnbflmpsvz",
"o",
1,
"o","a","ovi","a","o","ovi","em"
};
//vzor quasimodo resici pripad koncovky '-odo'.
//Odo, oda, odovi, oda, odo, odovi, odem
TVZOR pritel=
{
"e",
"c‡<EFBFBD>j¤©¨źbflmpsvz",
0,
"-","e","i","e","i","i","em"
};
//vzor pritel pro vzor muz pro obojetne souhlasky ze samohlaskou e,
TVZOR muz=
{
"*",
"c‡<EFBFBD>j¤©¨ź",
0,
"-","e","i","e","i","i","em"
};
//vzor muz
TVZOR fenix=
{
"*",
"x",
0,
"-","e","ovi","e","i","ovi","em"
};
//vzor pro jmena koncici -x
TVZOR predseda=
{
"hkrdtnbpvz",
"a o˘uŁy<EFBFBD>",
1,
"a","y","ovi","u","o","ovi","ou"
};
//vzor predseda
TVZOR soudce=
{
"c‡<EFBFBD>j¤©¨źflmsx",
"eiˇo˘uŁ",
1,
"e","e","i","e","e","i","em"
};
//vzor soudce
TVZOR soudce2=
{
"dtn",
"<EFBFBD>",
1,
"e","e","i","e","e","i","em"
};
//vzor soudce pro tvrdou koncovku s mekkou samohlaskou -di -ti -ni
//-de -te -ne.
//Nasledujici funkce vraci 1 pokud jmeno muze byt sklonovano vzorem vz
char test_vzor(TVZOR *vz,char *jmeno)
{
char *end;
char testchar;
end=strchr(jmeno,0)-2;
testchar=end[0];
if (vz->znak1[0]!='*' && strchr(vz->znak1,testchar)==NULL) return 0;
testchar=end[1];
if (vz->znak2[0]!='*' && strchr(vz->znak2,testchar)==NULL) return 0;
return 1;
}
//tato funkce se vola p©ed odejmutˇm ur‡itho znaku.
//Pokud to toti je zm<7A>k‡ovacˇ samohl ska, musˇ se p©ˇpadn d,t,n
//zm<7A>k‡it p©ed touto samohl skou.
void odejmi_znak(char *znak)
{
if (znak[0]=='<EFBFBD>' || znak[0]=='ˇ' || znak[0]=='i')
switch (znak[-1])
{
case 'd': znak[-1]='<EFBFBD>';break;
case 't': znak[-1]='ź';break;
case 'n': znak[-1]='¤';break;
}
}
//Tato funkce upravuje nektere pady jen maji predpredposledni samohlasku e
//Marek => Marka
//Pisen => Pisne
//Zdenek => Zdenka
void uprav_e_nakonci(char *konec)
{
char samohlasky[]="a eiˇo˘uŁy<EFBFBD>";
char pismena[]="flmn¤r©s¨xpv";
char *c;
c=konec-2;
if (strchr(samohlasky,c[2])!=NULL && strchr(samohlasky,c[1])==NULL && strchr(pismena,c[-1])!=NULL)
if (c[0] =='e'|| c[0]==''|| c[0] =='<EFBFBD>')
{
odejmi_znak(c);
strcpy(c,c+1);
}
}
//Naplni buffer spravnym padem jmena podle vzoru vz
//paduje se od 0 => 1. pad
void ziskej_pad(char *buffer,char *jmeno,TVZOR *vz,char pad)
{
char *end;
strcpy(buffer,jmeno);
if (vz->pady[pad][0]=='-') return;
end=strchr(buffer,0)-vz->chrdel;
odejmi_znak(end); //odejme znak, pokud je => znak 0 neni znak cesky.
strcpy(end,vz->pady[pad]);
if (pad && !vz->chrdel && end[-2]=='') end[-2]='o';
uprav_e_nakonci(end);
return;
}
//Tato funkce upravi nektere specialni dvojice znaku do spravne podoby
//prvni sloupec je puvodni dvojice, druhy sloupec je nova dvojice
void uprav_dvojice(char *jmeno)
{
static char *dvojice[]=
{
"<EFBFBD>e","d<EFBFBD>",
"źe","t<EFBFBD>",
"¤e","n<EFBFBD>",
"<EFBFBD>i","di",
"źi","ti",
"¤i","ni",
"<EFBFBD>ˇ","",
"źˇ","",
"¤ˇ","",
"r<EFBFBD>","©e",
"s<EFBFBD>","¨e",
"c<EFBFBD>","‡e",
"k<EFBFBD>","ce",
"¨<EFBFBD>","¨e",
"<EFBFBD>","e",
"<EFBFBD>","‡e",
"©<EFBFBD>","©e",
};
while (*jmeno)
{
int i;
for(i=0;i<sizeof(dvojice)/sizeof(char *);i+=2)
{
if (!strncmp(jmeno,dvojice[i],2))
{
strncpy(jmeno,dvojice[i+1],2);
break;
}
}
jmeno++;
}
}
//Pole padovych predlozek
char *jmena_padu[]=
{
"kdo",
"bez",
"k",
"vidˇm",
"vol m",
"o",
"s"
};
//Tato funkce zobrazi vypadovane jmeno
void show_table(char *jmeno,TVZOR *vz,char tabnum)
{
int i;
char *buff;
buff=alloca(strlen(jmeno)+20);
printf("%d. monost\n\n",tabnum);
for(i=0;i<7;i++)
{
if (i)
{
ziskej_pad(buff,jmeno,vz,i);
uprav_e_nakonci(buff);
}
else strcpy(buff,jmeno);
uprav_dvojice(buff);
printf(" %d. %-6s %s\n",i+1,jmena_padu[i],buff);
}
printf("**** Kl vesu ****\n");
getche();
}
//Tato funkce vypise celkovy vysledek.
void notabs(int i)
{
if (i) printf("Program na¨el %d momost%s.\n",i,(i!=1?(i>1 && i<5?"i":"ˇ"):""));
else printf("Program bohuel nena¨el  dnou monost jak sklo¤ovat toto jmno.\n");
puts("-------------------------------------------------------------------------");
}
//Tato funkce zobrazi vsechny moznosti padovani pro rod zensky
void hledej_zena(char *jmeno)
{
int tabnum=0;
if (test_vzor(&zena,jmeno)) show_table(jmeno,&zena,++tabnum);
if (test_vzor(&natasa,jmeno)) show_table(jmeno,&natasa,++tabnum);
if (test_vzor(&ruze,jmeno)) show_table(jmeno,&ruze,++tabnum);
if (test_vzor(&ruze2,jmeno)) show_table(jmeno,&ruze2,++tabnum);
if (test_vzor(&pisen,jmeno)) show_table(jmeno,&pisen,++tabnum);
if (test_vzor(&kost,jmeno)) show_table(jmeno,&kost,++tabnum);
notabs(tabnum);
}
//Tato funkce zobrazi vsechny moznosti padovani pro rod muzsky
void hledej_muz(char *jmeno)
{
int tabnum=0;
if (test_vzor(&pritel,jmeno)) show_table(jmeno,&pritel,++tabnum);
if (test_vzor(&pan,jmeno)) show_table(jmeno,&pan,++tabnum);
if (test_vzor(&pan2,jmeno)) show_table(jmeno,&pan2,++tabnum);
if (test_vzor(&muz,jmeno)) show_table(jmeno,&muz,++tabnum);
if (test_vzor(&quasimodo,jmeno)) show_table(jmeno,&quasimodo,++tabnum);
if (test_vzor(&predseda,jmeno)) show_table(jmeno,&predseda,++tabnum);
if (test_vzor(&soudce,jmeno)) show_table(jmeno,&soudce,++tabnum);
if (test_vzor(&soudce2,jmeno)) show_table(jmeno,&soudce2,++tabnum);
if (test_vzor(&fenix,jmeno)) show_table(jmeno,&fenix,++tabnum);
notabs(tabnum);
}
//Hlavni cast programu
void hlavni()
{
char jmeno[51];
char pohlavi;
do
{
printf("Zadej jmno. Vyaduje se min 3 znaky v ‡e¨tin<69> kodu kamenick<63>ch \n");
printf("Jmno nesmˇ mˇt vˇc ne 50 znak, a nesmˇ obsahovat mezery:\n");
printf("Pi¨ mal<61>mi pˇsmeny, pouze prvnˇ pismeno me b<>t velk:\n");
printf("(pouh 'x' je odchod z programu)\n");
jmeno_chyba:
gets(jmeno);
if (jmeno[0]=='x' && jmeno[1]==0) return;
if (strlen(jmeno)<3)
{
printf("Jmno musˇ b<>t min 3 znaky dlouh\n");
goto jmeno_chyba;
}
chyba:
printf("Jsi mu nebo ena? (M/Z nebo M/F nebo X):");
pohlavi=getchar();
while (getchar()!='\n');
puts("");
pohlavi=toupper(pohlavi);
if (pohlavi=='X') return;
if (pohlavi=='M') hledej_muz(jmeno);
else if (pohlavi=='F' || pohlavi=='Z') hledej_zena(jmeno);
else goto chyba;
}
while (1);
}
main()
{
hlavni();
puts("");
puts("Pokud jsi objevil p©irozen jmno (tj re ln jmno), kter program\n"
"nedok zal vysklo¤ovat, po¨li mi jeho zn<7A>nˇ na adresu:\n"
"xnovako1@cs.felk.cvut.cz\n");
puts("Verze Latin2 se p©ipravuje...\n"
"O slovensk verzi se zatˇm neuvauje...\n");
puts("Napsal: Ond©ej Nov k za 2 a pl hodiny ve WATCOM C\n"
"Zdroj ky majˇ povahu PUBLIC DOMAIN\n");
}

304
libs/pcspeak.asm Normal file
View file

@ -0,0 +1,304 @@
.model small
.386P
DGROUP group _DATA
;real procedura pro prehravani na PCSPEAKERu.
;Tato procedura musi obsahovat vsechny deklarace, ktere vyuziva Protect Mode
;Tyto deklarace jsou pristupne i s PM. Opacne to vsak nelze
rl_pm_bufseg equ (offset pm_bufseg-rm_proc)
rl_bufseg equ (offset bufseg-rm_proc)
rl_bufpos equ (offset bufpos-rm_proc)
rl_port equ (offset port-rm_proc)
rl_xlattab equ (offset xlattab-rm_proc)
_TEXT16 segment byte public 'CODE' use16
assume cs:_TEXT16
assume ds:_TEXT16
rm_proc: ;Zde zacina obsluha INT 8 z realu
cli
push ds ;Program nevstupuje do dalsich int kvuly zdrzovani
push ax ;Nejprve se ulozi vsechny ohrozene registry
push bx
push dx
push si
mov ax,cs:[rl_bufseg]
mov ds,ax ;ds segment ukazuje na buffer
mov dx,cs:[rl_port] ;nacti adresu portu
lea bx,cs:[rl_xlattab];nacti zacatek
mov si,cs:[rl_bufpos];nacti si - adresu prehravaneho bytu
lods ds:[si] ;precti byte
mov cs:[rl_bufpos],si;uloz si
add bl,al
adc bh,0
mov al,cs:[bx]
out dx,al ;posli ho na port
mov al,20h
out 20h,al ;posli end of interrupt
pop si ;obnov se ulozene.
pop dx
pop bx
pop ax
pop ds
iret
bufseg dw 0x1234 ;segment kde je ulozen playing buffer
;predpoklada se ze je 64Kb dlouhy.
bufpos dw ? ;ukazatel na aktualni prehravana data
;data jsou v bufferu ulozena unsigned
port dw ? ;cislo portu, kam je nutne data posilat
pm_bufseg dw ? ;buffer z protectu
xlattab db 256 dup (?) ;prekladova tabulka pro PC_SPEAK.
;pro DAC vyplnte cisli 0 - 255
rm_konec: ;ukazatel na konec rm_proc
_TEXT16 ends
.data
old8rmofs dw ?
old8rmseg dw ?
old8pmofs dd ?
old8pmseg dw ?
rmproc_rmseg dw ? ;segment rm_proc v realnem rezimu
rmproc_pmseg dw ? ;segment rm_proc v chranenem rezim
timer dw ? ;hodnota casovace pro simulaci puvodni INT 8
timer_max dw ? ;max hodnota casovace
zavora db 0 ;zavora do pm_proc
SPKTAB Db 20h, 1fh, 1eh, 1dh, 1ch, 1bh, 1ah, 19h, 18h, 17h, 16h, 15h, 14h, 13h
Db 12h, 11h, 11h, 10h, 10h, 0fh, 0fh, 0eh, 0eh, 0dh, 0dh, 0dh, 0ch, 0ch, 0ch, 0ch
Db 0bh, 0bh, 0bh, 0bh, 0Ah, 0ah, 0ah, 0ah, 0ah, 09h, 09h, 09h, 09h, 09h, 09h, 09h
Db 09h, 08h, 08h, 08h, 08h, 08h, 08h, 08h, 08h, 08h, 08h, 08h, 08h, 08h, 07h, 07h
Db 07h, 07h, 07h, 07h, 07h, 06h, 06h, 06h, 06h, 06h, 06h, 06h, 06h, 06h, 06h, 06h
Db 05h, 05h, 05h, 05h, 05h, 05h, 05h, 05h, 05h, 05h, 04h, 04h, 04h, 04h, 04h, 04h
Db 04h, 04h, 04h, 04h, 03h, 03h, 03h, 03h, 03h, 03h, 03h, 03h, 03h, 03h, 02h, 02h
Db 02h, 02h, 02h, 02h, 02h, 02h, 02h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h
Db 01h, 01h ;prekladova tabulka pro speakra.
db 40h, 40h, 40h, 40h, 40h, 40h, 40h, 40h, 40h, 40h, 3fh, 3fh, 3fh, 3fh
Db 3fh, 3fh, 3fh, 3fh, 3fh, 3fh, 3fh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh, 3eh
Db 3eh, 3eh, 3dh, 3dh, 3dh, 3dh, 3dh, 3dh, 3dh, 3dh, 3dh, 3ch, 3ch, 3ch, 3ch, 3ch
Db 3ch, 3ch, 3ch, 3ch, 3ch, 3bh, 3bh, 3bh, 3bh, 3bh, 3bh, 3bh, 3bh, 3bh, 3bh, 3ah
Db 3ah, 3ah, 3ah, 3ah, 3ah, 3ah, 3ah, 3ah, 3ah, 39h, 39h, 39h, 39h, 39h, 39h, 39h
Db 39h, 39h, 39h, 38h, 38h, 38h, 38h, 38h, 38h, 38h, 38h, 37h, 37h, 37h, 37h, 37h
Db 36h, 36h, 36h, 36h, 35h, 35h, 35h, 35h, 34h, 34h, 34h, 33h, 33h, 32h, 32h, 31h
Db 31h, 30h, 30h, 2fh, 2eh, 2dh, 2ch, 2bh, 2ah, 29h, 28h, 27h, 26h, 25h, 24h, 23h
Db 22h, 21h
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
public load_rm_proc_ ;funkce nacte rm_proc do realne pameti
load_rm_proc_ :
mov ebx,(rm_konec-rm_proc+16) shr 4 ;velikost v paragrafech
mov eax,100h
int 31h ;alokuj DOS pamet
mov rmproc_rmseg,ax ;segment
mov rmproc_pmseg,dx ;selektor
sbb al,al ;al=0xff pri chybe
jc lrmp_e ;skok pri chybe
push es ;uchovej segmentove registry
push ds
mov es,dx
xor edi,edi
mov dx,ds
mov ds,dx
mov esi,offset rm_proc
mov ecx,(rm_konec-rm_proc)
rep movsb ;presun rm_proc z protect mem do real mem
pop ds
pop es
lrmp_e: ret
public purge_rm_proc_ ;funkce uvolni rm_proc z pameti
purge_rm_proc_:
mov dx,rmproc_pmseg
mov eax,101h
int 31h ;dealokuj
sbb al,al ;al obsahuje chybu
ret
;tutu proceduru je nutne volat jako posledni!
public rm_proc_set_ ;funkce nastavuje promenne v rm_proc
;ax - bufseg - rm adresa bufferu
;dx - bufseg - pm adresa bufferu
;cx - adresa portu
;bx - mod XLAT - 0 normal mode
; 1 pcspeak mode
assume es:_TEXT16
rm_proc_set_:
push es ;uloz es
mov si,ds ;seg bufseg
mov es,si
mov es:bufseg,ax ;zapis rm bufseg
mov es:pm_bufseg,dx ;zapis pm bufseg
mov es:port,cx ;zapis cislo portu
or bx,bx ;test bx
jz rps_nrm ;je li nulovy - normal mode
lea esi,SPKTAB ;vem spktab
lea edi,es:xlattab
mov ecx,256
rep movsb ;prenes ji do xlattab
jmp rps_pcs
rps_nrm:xor ah,ah ;al =0
mov al,80h
lea edi,es:xlattab
rps_nr1:stosb ;zapis al do xlattab
inc al ;al=al+1
inc ah
jnz rps_nr1 ;dokud to nebude cela tabulka
rps_pcs:pop es ;obnov es
ret
;POZNAMKA: tato procedura modifikuje data v originalnim vzoru. Proto ji je
;nutne volat pred vlastnim load_rm_proc
pc_speak_protect: ;funkce pro obsluhu pcspeak v protect mode
push ds
push es ;uchovej ohrozene registry
push eax
push ebx
push edx
push esi
mov ax,seg _DATA
mov ds,ax
mov ds,ds:rmproc_pmseg ;nacti ukazatel na datovou oblast v rmm
assume ds:_TEXT16
mov ebx,rl_xlattab ;nacti ukazatel na xlattab
movzx edx,word ptr ds:[rl_port] ;nacti cislo portu
movzx esi,word ptr ds:[rl_bufpos] ;nacti ukazatel na vzorek
mov es,word ptr ds:[rl_pm_bufseg] ;nacti pm_selector na buffer
lods byte ptr [es:esi];precti sample
mov word ptr ds:[rl_bufpos],si;uloz ukazatel na dalsi vzorek
xlatb ;preloz podle xlattab
out dx,al ;posli ho na port
mov ax,seg _DATA ;vem selector na globalni data
mov ds,ax ;napln jim ds
assume ds:DGROUP
mov al,20h ;posli eoi
out 20h,al
dec timer ;sniz citac
jnz pcs_p1 ;pokud neni na nule, skoc na konec
mov ax,timer_max ;napln citac maximalni hodnotou
mov timer,ax
cmp zavora,0 ;odtestuj zavoru
jnz pcs_p1 ;zavrena zavora by zpusobila preplneni INT8
mov zavora,1 ;zavri zavoru
pushfd ;uchovej flagy - simuluj INT
sti ;povol preruseni (vsechna preruseni na INT8 projdou zavorou)
call far dword ptr[old8pmofs] ;skok do puvodniho osetreni INT8
mov zavora,0 ;zakazovat int neni treba, jeho stav je ulozen ve flags
pcs_p1: pop esi ;otevri zavoru - obnov registry
pop edx
pop ebx
pop eax
pop es
pop ds
iretd ;konec obsluhy preruseni.
public pc_speak_run_ ;funkce instaluje bimodalni ovladac PCSPEAK
pc_speak_run_:
;eax - sample freq
;edx - frekvence simulace int 8 (18.2 HZ)
cli ;zakaz preruseni
push eax ;tyto parametry zatim nejsou potreba
push edx
mov eax,200h ;nejprve zjisti puvodni obsluhu RM
mov bl,8 ;INT 8
int 31h
mov old8rmofs,dx ;uloz hodnoty
mov old8rmseg,cx
mov eax,204h ;pak precti starou obsluhu PM
int 31h
mov old8pmofs,edx ;uloz hodnoty
mov old8pmseg,cx
mov eax,205h ;nastav novou obsluju PM
mov cx,cs
mov edx,offset pc_speak_protect
int 31h
mov eax,201h ;nastav novou obsluhu RM
mov cx,rmproc_rmseg
mov dx,0
int 31h
pop ebx ;obnov sample freq
pop eax ;obnov simint freq -> do ebx!
mov ecx,eax ;sample freq uchovej jeste v ecx
xor edx,edx ;vynuluj edx, horni polovina edx&eax
div ebx ;delenim ziskej timer (samplef/simintf)
mov timer,ax ;uloz timer -> deleni neni presne ale v ramci
mov timer_max,ax ;presnosti vyhovuje
mov eax,1234dch ;ziskej nastaveni 8253 delenim zakladni freqvence
xor edx,edx
div ecx ;to je ted v eax
mov ecx,eax ;uchovej ho v ecx
mov al,34h ;citac 1 word rezim 2 - 1:m
out 43h,al ;zapis nastaveni
mov al,cl ;dolni hodnotu citace
out 40h,al
mov al,ch ;horni hodnotu citace
out 40h,al
sti ;povol preruseni
ret
public pc_speak_stop_ ;tato funkce zasatvi prehravani PCSPEAK a vrati puvodni vektory
pc_speak_stop_:
cli
mov al,36h ;nejprve zpomal casovace
out 43h,al
mov al,0
out 40h,al
out 40h,al
mov bl,8
mov eax,201h ;vrat puvodni rm vektor
mov cx,old8rmseg
mov dx,old8rmofs
int 31h
mov eax,205h ;vrat puvodni pm vektor
mov cx,old8pmseg
mov edx,old8pmofs
int 31h
sti
ret
public pc_speak_enable_ ;povoluje prehravani na PCSpeaker(TM)
pc_speak_enable_: ;nastavuje specialni rezim prehravani.
in al,61H
or al,3
out 61H,al
mov AL,90H
out 43H,al
ret
public pc_speak_disable_ ;zakazuje prehravani na PCSpeaker(TM)
pc_speak_disable_: ;funkce defacto vraci puvodni nastaveni.
SPKOFF: in al,061H
and al,0FCH
out 61H,al
ret
public pc_speak_position_ ;ziska aktualni pozici
pc_speak_position_:
push es
mov es,rmproc_pmseg
movzx eax,word ptr es:[rl_bufpos]
movzx ebx,word ptr es:[rl_bufseg]
shl ebx,4
add eax,ebx
pop es
ret
public pc_speak_set_proc_ ;zapise na [edi] adresi na pc_speak_position_
pc_speak_set_proc_:
mov [edi],offset pc_speak_position_
ret
_TEXT ends
end

137
libs/pcspeak.h Normal file
View file

@ -0,0 +1,137 @@
#define SPK_MODE 1
#define DAC_MODE 0
#define PORT_LPT1 0x378
#define PORT_LPT2 0x278
#define PORT_SPK 0x42
#define UWORD unsigned short
void rm_proc_set(UWORD bufseg,UWORD bufsel,UWORD port,UWORD mode);
#pragma aux rm_proc_set parm [eax][edx][ecx][ebx] modify [esi edi]
char load_rm_proc(void);
#pragma aux load_rm_proc modify [eax ebx ecx edx esi edi] value [al]
char purge_rm_proc(void);
#pragma aux purge_rm_proc modify [edx eax] value [al]
void pc_speak_run(long s_freq,long sim_freq);
#pragma aux pc_speak_run parm[eax][edx] modify [ecx ebx]
void pc_speak_stop(void);
#pragma aux pc_speak_stop modify [eax ebx ecx edx]
void pc_speak_enable(void);
#pragma aux pc_speak_enable modify [eax]
void pc_speak_disable(void);
#pragma aux pc_speak_enable modify [eax]
long pc_speak_position(void);
#pragma aux pc_speak_position modify[eax ebx] value [eax]
void pc_speak_set_proc(long *c);
#pragma aux pc_speak_set_proc parm [edi]
/* Zde jsou nejake komentare */
/*
void rm_proc_set;
Vstup: bufseg - segmen bufferu v konvenci realneho rezimu
bufsel - selektor tohoto segmentu (protect rezim)
port - cislo portu - je mozne vyuzit konstant PORT_LPT? nebo PORT_SPK
mode - zde vyuzij konstant SPK_MODE nebo DAC_MODE podle zarizeni.
Vystup: -
Komentar: Podprogram nastavuje parametry rm procedury pro spravne prehravani
Je nutne provest pred load_rm_proc.
MODE musi korespondovat s PORTem, je-li PORT=PORT_SPK, pak
MODE=SPK_MODE
Nemusim doufam rikat ze bufseg a bufsel musi popisovat stejny
segment.
-------------------------------------------------------------------
void load_rm_proc;
Vstup: -
Vystup:nenulova hodnota v pripade nedostatku dolni pameti.
Komentar: Funkce nahraje do realne pameti (do 1MB) rm_proc pro prehravani
Rm_proc pak zajisti spravnou obsluhu preruseni v realnem rezimu
-------------------------------------------------------------------
void purge_rm_proc;
vstup: -
Vystup:nenulova hodnota oznamuje ze se nepodarilo rm_proc uvolnit z pameti.
Komentar: Funkce uvolni pamet, ktera byla alokovana funkci load_rm_proc.
Tim dojde ke zniceni rm_proc.
-------------------------------------------------------------------
void pc_speak_run;
vstup: s_freq - samplovaci frekvence v Hz (treba 22050)
sim_freq - frekvence simulace INT 8. Bezne 18Hz. (frekvence je priblizna)
vystup:zacne se prehravat
Komentar: Funkce alokuje preruseni INT 8 a spusti ho rychlosti danou S_FREQ.
pm_proc se navic simuluje puvodni INT 8 frekvenci sim_freq.
simulace INT 8 neprobiha v realnem rezimu, pouze v chranennem.
(pozor na DOS). Behem simulace je preruseni povolene (chranenne
zavorou v pm_proc). Pokud chces pouzivat INT 8, nesmis zakazovat
preruseni behem jeho zpracovavani, zabranis tak casovym ztratam
na INT 8.
-------------------------------------------------------------------
void pc_speak_stop;
vstup: -
vystup:-
Komentar: Zastavi prehravani. Hodiny neobnovuje - spravny cas si
musis nastavit sam (nejlepe z CMOS).
-------------------------------------------------------------------
void pc_speak_enable;
void pc_speak_disable;
enable - zapina PC SPEAKER v rezimu 6-bitoveho DAC.
disable - vraci nastaveni PC SPEAKERu zpet do puvodniho rezimu.
-------------------------------------------------------------------
long pc_speak_position(void);
Vstup: -
Vystup: long offset do bufferu. Vraci prave preravanou pozici
Komentar: sice vraci long, ale offset je v rozsahu <0-64Kb>. Vzhledem k
casovym ztratam muze vracena pozice byt starsi uz v dobe
predavani vysledku. Presnost zavisi na rychlosti pocitace.
-------------------------------------------------------------------
void pc_speak_set_proc;
Vstup: Ukazatel na ukazatel na void (ackoliv je tam long *)
Vystup:-
Komentar: Procedura modifikuje promennou kam ukazuje parametr tak aby
obsahovala adresu na proceduru pc_speak_position.
Volanim teto adresy lze pak docilit stejne funkce jako
volanim primeho pc_speak_position.
Oba zpusoby jsou rovnocenne.
-------------------------------------------------------------------
Doporuceny postup:
rm_proc_set(...);//Nastav rm_proc
load_rm_proc(); //nahraj rm_proc do dolni pameti
pc_speak_enable(); //PCSPEAKER do modu DAC (pokud se hraje na spk)
pc_speak_run(...); //Zacni prehravat buffer
......
pc_speak_stop(); //Zastav prehravani
pc_speak_disable(); //PCSPEAKER vrat do normalniho rezimu
purge_rm_proc(); //vymaz rm_proc z dolni pameti
*/

210
libs/pcx.c Normal file
View file

@ -0,0 +1,210 @@
#include <skeldal_win.h>
#include <malloc.h>
#include <mem.h>
#include <stdio.h>
/*#include "..\types.h"*/
#include "pcx.h"
#include "memman.h"
/*#include "..\bgraph.h"*/
#define SHADE_STEPS 5
#define SHADE_PAL (SHADE_STEPS*512*2)
void *get_palette_ptr=NULL;
void decomprimate_line_256(char *src,char *trg,int linelen,int *srcstep)
{
char *srcsave;
srcsave=src;
while (linelen--)
{
if (*src>=0xc0)
{
int i;
i=*src++ & 0x3f;memset(trg,*src++,i);
trg+=i;linelen-=i-1;
}
else
*trg++=*src++;
}
*srcstep=src-srcsave;
}
void decomprimate_line_hi(char *src,unsigned short *trg,unsigned short *paleta,int linelen,int *srcstep)
{
char *srcsave;
srcsave=src;
while (linelen--)
{
if (*src>=0xc0)
{
int i,j;
i=(*src++) & 0x3f;
for (j=0;j<i;j++) *trg++=paleta[*src];
src++;
linelen-=i-1;
}
else
*trg++=paleta[*src++];
}
*srcstep=src-srcsave;
}
void palette_shadow(char *pal1,unsigned short pal2[][256],int tr,int tg,int tb)
{
int i,j;
char *bt;
int r,g,b;
short hi;
for (j=0;j<SHADE_STEPS;j++)
{
bt=pal1;
i=0;
do
{
r=(tr+(*(bt++)-tr)*(3*SHADE_STEPS-3*j-1)/(3*SHADE_STEPS-1))>>3;
g=(tg+(*(bt++)-tg)*(3*SHADE_STEPS-3*j-1)/(3*SHADE_STEPS-1))>>3;
b=(tb+(*(bt++)-tb)*(3*SHADE_STEPS-3*j-1)/(3*SHADE_STEPS-1))>>3;
hi=(r<<11)+(g<<6)+b;
pal2[j][i]=hi;
}
while (++i & 0xff);
}
for (j=0;j<SHADE_STEPS;j++)
{
bt=pal1;
i=0;
do
{
r=((*(bt++))*(SHADE_STEPS-j)/SHADE_STEPS)>>3;
g=((*(bt++))*(SHADE_STEPS-j)/SHADE_STEPS)>>3;
b=((*(bt++))*(SHADE_STEPS-j)/SHADE_STEPS)>>3;
hi=(r<<11)+(g<<6)+b;
pal2[j+SHADE_STEPS][i]=hi;
}
while (++i & 0xff);
}
}
int load_pcx(char *pcx,long fsize,int conv_type,char **buffer, ... )
//dale nasleduji int hodnoty poctu prechodu a R,G,B barvy
{
unsigned short paleta2[256];
char *paleta1;
char *ptr1;unsigned short *ptr2;
char *ptr3;
int i;
PCXHEADER pcxdata;
int xsize,ysize;
if (pcx==0) return -1;
paleta1=pcx+fsize-768;
ptr1=paleta1;ptr2=paleta2;
if (get_palette_ptr!=NULL)
memcpy(get_palette_ptr,ptr1,768);
for (i=0;i<256;i++)
{
*ptr2=*(ptr1++)>>3;
*ptr2=(*ptr2<<5)+(*(ptr1++)>>3);
*ptr2=(*ptr2<<6)+(*(ptr1++)>>3);
ptr2++;
}
memcpy(&pcxdata,pcx,sizeof(pcxdata));
xsize=pcxdata.xmax-pcxdata.xmin+1;
ysize=pcxdata.ymax-pcxdata.ymin+1;
int sz = 0;
switch (conv_type)
{
case A_8BIT: *buffer=(char *)getmem(sz = xsize*ysize+512+16);break;
case A_16BIT: *buffer=(char *)getmem(sz = xsize*ysize*2+16);break;
case A_FADE_PAL: *buffer=(char *)getmem(sz = xsize*ysize+SHADE_PAL+16);break;
case A_8BIT_NOPAL: *buffer=(char *)getmem(sz = xsize*ysize+16);break;
case A_NORMAL_PAL: *buffer=(char *)getmem(sz = xsize*ysize+16+768);break;
default: return -2; //invalid type specificied
}
ptr1=*buffer;
*(unsigned short *)ptr1++=xsize;ptr1++;
*(unsigned short *)ptr1++=ysize;ptr1++;
*(unsigned short *)ptr1++=conv_type;ptr1++;
pcx+=sizeof(pcxdata);ptr3=pcx;
if (conv_type==A_NORMAL_PAL)
{
memcpy(ptr1,paleta1,768);
ptr1+=768;
}
if (conv_type==A_8BIT)
{
memcpy(ptr1,paleta2,512);
ptr1+=512;
}
if (conv_type==A_FADE_PAL)
{
int *i,tr,tg,tb;
i=(int *)&buffer;i++;
tr=*i++;tg=*i++;tb=*i++;
palette_shadow(paleta1,(unsigned short (*)[256])ptr1,tr,tg,tb);
ptr1+=SHADE_PAL;
}
ysize++;
while (--ysize)
{
int step;
if (conv_type==A_16BIT)
{
decomprimate_line_hi(ptr3,(unsigned short *)ptr1,paleta2,pcxdata.bytesperline,&step);
ptr1+=2*xsize;
}
else
{
decomprimate_line_256(ptr3,ptr1,pcxdata.bytesperline,&step);
ptr1+=xsize;
}
ptr3+=step;
}
return sz;
}
int open_pcx(char *filename,int type,char **buffer,...)
{
FILE *pcx;
char *src;
long fsize;
pcx=fopen(filename,"rb");
if (pcx==NULL) return -1;
fseek(pcx,0,SEEK_END);
fsize=ftell(pcx);
fseek(pcx,0,SEEK_SET);
src=(char *)getmem(fsize);
fread(src,1,fsize,pcx);
fsize=load_pcx(src,fsize,type,buffer,*((int *)&buffer+1),*((int *)&buffer+2),*((int *)&buffer+3));
fclose(pcx);
free(src);
return fsize;
}
/*void initmode32b();
main()
{
char *buf;
initmode32b();
open_pcx("DESK.pcx",A_8BIT,&buf,0,0,0);
put_picture(0,480-102,buf);
showview(0,0,0,0);
getchar();
return 0;
}
*/

42
libs/pcx.h Normal file
View file

@ -0,0 +1,42 @@
#ifndef _PCX_H_
#define _PCX_H_
#ifdef __cplusplus
extern "C" {
#endif
#define A_8BIT 8
#define A_16BIT 16
#define A_FADE_PAL (256+8)
#define A_8BIT_NOPAL (512+8)
#define A_NORMAL_PAL (768+8)
#pragma pack(1)
typedef struct pcxrecord
{
unsigned short id;
char encoding;
char bitperpixel;
unsigned short xmin,ymin,xmax,ymax;
unsigned short hdpi,vdpi;
char colormap[48];
char reserved;
char mplanes;
unsigned short bytesperline;
unsigned short paleteinfo;
unsigned short hscreen,vscreen;
char filler[54];
}PCXHEADER;
#pragma pack()
//returns <0 error, >0 allocated size
int load_pcx(char *pcx,long fsize,int conv_type,char **buffer, ... );
int open_pcx(char *filename,int type,char **buffer,...);
void palette_shadow(char *pal1,unsigned short pal2[][256],int tr,int tg,int tb);
extern void *get_palette_ptr;
#ifdef __cplusplus
}
#endif
#endif

181
libs/readfont.c Normal file
View file

@ -0,0 +1,181 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <mem.h>
#include "types.h"
#include "pcx.h"
#include "memman.h"
int xs,ys;
char *pic;
char font_buffer[65536];
word font_p=0;
word char_table[256];
int top_line;
int bott_line;
int base_line;
int top_ofs;
char znaky[]="0123456789A<EFBFBD>BC€D…E<EFBFBD>‰FGHIJKLŠœMN¥O•PQRžST†U—¦VWXY<EFBFBD>Z"
"a bc‡dƒeˆfghi¡jkl<EFBFBD>Œmn¤o¢pqr©s¨tŸu£vwxy˜z"
"~!@#$%^&*()_+|-=\\[]{};':,./<>?";
void load_font_pic(char *filename)
{
open_pcx(filename,A_8BIT_NOPAL,&pic);
memcpy(&xs,pic,2);
memcpy(&ys,pic+2,2);
top_line=0;
base_line=0;
bott_line=-1;
}
char get_point(int x,int y)
{
return *(pic+xs*y+x+6);
}
int find_lead(int last)
{
last++;
while (last<ys) if (get_point(0,last)!=255) return last;else last++;
return -1;
}
int follow_lead(int y)
{
int x=0;
while (get_point(x,y)!=255) x++;
return x;
}
int get_top_extend(int lead,int last_top) //vraci nejhorejsi souradnici
{
int x;
last_top++;
while (last_top<lead)
{
for(x=0;x<xs;x++) if (get_point(x,last_top)==0) return last_top;
last_top++;
}
return -1;
}
int get_bott_extend(int lead) //vraci nejspodnejsi souradnici
{
int x,y,ok;
y=lead;ok=1;
while (ok)
{
ok=0;
for(x=0;x<xs;x++) if (get_point(x,y)==0) ok=1;
y+=ok;
}
return y;
}
char write_accl(char *where,int accl)
{
if (accl==0) return 0;
if (accl==1) *where=0;else *where=accl+6;
return 1;
}
void lead_up_line(int *x,int *y)
{
base_line=find_lead(base_line);
if (base_line==-1) return;
*x=follow_lead(base_line);
top_line=get_top_extend(base_line,bott_line);
bott_line=get_bott_extend(base_line);
*y=base_line;
}
int find_next_char(int x,int top,int bott)
{
int y;
while (x<xs)
{
for (y=top;y<bott;y++) if (get_point(x,y)==0) return x;
x++;
}
return -1;
}
char *read_char(char *pos,int *x,int top,int bott)
{
char accl=0;
char *xinfo;
char space=0;
int y;
xinfo=pos++;*xinfo=0;
*pos++=bott-top+1;
do
{
space=1;
for (y=top;y<=bott;y++)
{
if (get_point(*x,y)==255) accl++;
else pos+=write_accl(pos,accl),*pos++=2,space=accl=0;
}
xinfo[0]++;
x[0]++;
}
while (!space);
*pos++=255;
return pos;
}
word recognize()
{
char *zn=znaky;
int x,y;
char *fp;
memset(char_table,0,sizeof(char_table));
fp=font_buffer;
lead_up_line(&x,&y);
while (base_line>=0)
{
x=base_line-top_line;
if (x>top_ofs) top_ofs=x;
lead_up_line(&x,&y);
}
base_line=0;bott_line=-1;
do
{
lead_up_line(&x,&y);
top_line=base_line-top_ofs;
if ((x=find_next_char(x,top_line,bott_line))==-1) return fp-font_buffer;
while (*zn!=0 && x>0)
{
char_table[*zn]=(fp-font_buffer)+sizeof(char_table);
fp=read_char(fp,&x,top_line,bott_line);
x=find_next_char(x,top_line,bott_line);
zn++;
}
}
while (*zn);
return fp-font_buffer;
}
void save_font(char *filename,word bufsiz)
{
FILE *f;
f=fopen(filename,"wb");
fwrite(char_table,sizeof(char_table),1,f);
fwrite(font_buffer,bufsiz,1,f);
fclose(f);
}
void main()
{
word s;
load_font_pic("..\\font\\timese2.pcx");
s=recognize();
save_font("..\\font\\timese2.fon",s);
}

368
libs/strlists.c Normal file
View file

@ -0,0 +1,368 @@
#include <skeldal_win.h>
#include <debug.h>
#include "strlite.c"
#include "devices.h"
#include "event.h"
#include "bmouse.h"
#include "bgraph.h"
#include "gui.h"
#include "strlists.h"
#define SEC(t) (((t) & 0x1f)<<1)
#define MIN(t) (((t)>>5)& 0x3f)
#define HOUR(t) ((t)>>11)
#define DAY(t) ((t) & 0x1f)
#define MONTH(t) (((t)>>5)& 0x0f)
#define YEAR(t) ((t)>>9)
TSTR_LIST read_directory(char *mask,int view_type,int attrs)
{
TSTR_LIST flist;
int index=0;
char c[2*MAX_PATH];
WIN32_FIND_DATA s;
HANDLE h;
char rc;
flist=create_list(256);
if (flist==NULL) return flist;
h=FindFirstFile(mask,&s);
if (h!=INVALID_HANDLE_VALUE)
{
do
{
char d[MAX_PATH],*p;
int i=0;
if (attrs==_A_NORMAL || s.dwFileAttributes & attrs)
{
p=d;d[MAX_PATH-1]=0;
/* if (view_type!=DIR_NAMES)
{
while (s.cFileName[i]!='.' && s.cFileName[i]!='\0' ) *p++=s.cFileName[i++];
if (s.cFileName[i]!='\0') j=i+1;else j=i;
while (i<8)
{
*p++=32;i++;
}
i=3;
*p++='.';
while (s.name[j]!='\0')
{
*p++=s.name[j++];
i--;
}
while (i>0)
{
*p++=32;
i--;
}
}
else */strncpy(d,s.cFileName,MAX_PATH-1);
switch (view_type)
{
case DIR_FULL:sprintf(c,"%s %10d",
d,
s.nFileSizeLow
);
break;
case DIR_SHORT:sprintf(c,"%s %10d",d,s.nFileSizeLow);break;
case DIR_NAMES:
case DIR_BREIF:sprintf(c,"%s",d);break;
}
if (str_replace(&flist,index++,c)==NULL)
{
release_list(flist);
return NULL;
}
}
rc=FindNextFile(h,&s);
}
while (rc);
}
FindClose(h);
if (flist[0]==NULL)
{
release_list(flist);
return NULL;
}
sort_list(flist,-1);
str_delfreelines(&flist);
return flist;
}
void name_conv(char *c)
{
char *a,*b;
a=c;b=c;
while (*a) if (*a==32) a++; else *b++=*a++;
*b--='\0';
if (*b=='.') *b='\0';
}
typedef struct string_list_data
{
TSTR_LIST list;
int topline,maxitems,maxview;
int selcolor,skipshow;
int obj_win;
}
STRING_LIST_DATA;
void string_list_init(OBJREC *o,int *params)
{
STRING_LIST_DATA *p;
p=(STRING_LIST_DATA *)getmem(sizeof(STRING_LIST_DATA));
p->topline=0;
p->list=(TSTR_LIST)*params++;
p->selcolor=*params++;
p->skipshow=*params++;
o->userptr=p;
p->obj_win=waktual->id;
}
void string_list_change()
{
OBJREC *o1,*o2;
STRING_LIST_DATA *p;
o2=o_aktual;
o1=find_object(waktual,o2->id-1);
if (o1==NULL) return;
p=o1->userptr;
p->topline=f_get_value(0,o2->id);
redraw_object(o1);
}
static int get_to_topline(TSTR_LIST ls,int line,int *retu)
{
int cnt;
int ret,i,cn;
cnt=str_count(ls);ret=0;cn=0;
for(i=0;i<cnt;i++)
{
if (line>=0) ret=i;
if (ls[i]!=NULL) line--,cn++;
}
if (retu!=NULL) *retu=cn;
return ret;
}
static int set_line_back(TSTR_LIST ls,int line)
{
int i,c=-1,c1=str_count(ls);
if (line>=c1) line=c1-1;
for (i=0;i<=line;i++) if (ls[i]!=NULL) c++;
return c;
}
void string_list_draw(int x1,int y1,int x2,int y2,OBJREC *o)
{
STRING_LIST_DATA *p;
int xs,ys,y;
char savech[]=" ";
int znh,i,j,max;
TSTR_LIST ls;
int savcolor=curcolor;
xs=x2-x1;ys=y2-y1;
p=o->userptr;
ls=p->list;
bar(x1,y1,x2,y2);
y=y1;p->maxitems=str_count(ls);
for(j=p->maxitems-1;j>=0;j--) if (ls[j]!=NULL) break;
j++;
if (ls)
{
do
{
i=get_to_topline(ls,p->topline,&max);
p->maxview=0;
y=y1;
do
{
char *c;
int x,j;
c=ls[i];
if (c!=NULL && y+(znh=text_height(c))<y2)
{
j=p->skipshow;
while (j-- && *c) c++;
if (i==*(int *)(o->data))
{
curcolor=p->selcolor;
bar(x1,y,x2,y+znh-1);
}
position(x1,y);
for(j=0,x=x1,savech[0]=c[j];
c[j]!='\0' && x+text_width(savech)<x2;
j++,x+=text_width(savech),savech[0]=c[j]
)
outtext(savech);
y+=znh;
p->maxview++;
}
else
znh=0;
i++;
}
while (y+znh<y2 && i<p->maxitems);
if (p->topline && y+2*znh<y2 && znh)
{
int dif=y2-(y+znh);
p->topline-=(dif*2/3)/znh+1;
curcolor=savcolor;
bar(x1,y1,x2,y2);
}
}
while (p->topline && y+2*znh<y2 && znh);
}
if (waktual->id==p->obj_win)
{
OBJREC *ob;
ob=find_object(waktual,o->id+1);
if (ob!=NULL)
{
send_message(E_GUI,o->id+1,E_CONTROL,0,max-p->maxview,p->maxview);
ob->events[3]=string_list_change;
}
c_set_value(p->obj_win,o->id+1,p->topline);
}
}
void string_list_event(EVENT_MSG *msg,OBJREC *o)
{
STRING_LIST_DATA *p;
int y;
int znh,i;
TSTR_LIST ls;
MS_EVENT *ms;
static char clicked=0;
p=o->userptr;
ls=p->list;
y=o->locy;
switch (msg->msg)
{
case E_MOUSE:
i=get_to_topline(ls,p->topline,NULL);
ms=get_mouse(msg);
curfont=o->font;
if (ms->tl1 && clicked || ms->event_type & 0x2)
{
if (ls)
do
{
char *c;
clicked=1;
c=ls[i];
if (i>=p->maxitems) return;
if (c!=NULL) znh=text_height(c); else znh=0;
if (y+znh>o->locy+o->ys) return;
if (ms->y>=y && ms->y<y+znh)
{
if (ls[i]!=NULL) c_set_value(0,o->id,i);else clicked=0;
return;
}
i++;
y+=znh;
}
while (1);
}
if (ms->event_type & 0x4 && clicked)
{
clicked=0;set_change();
}
return;
case E_KEYBOARD:
{
int pos=*(int *)(o->data);
int key=(*(int *)msg->data) & 0xff;
if (!key)
{
int save;
int curLine;
key=*(int *)msg->data >> 8;
{
do
{
save=pos;
switch (key)
{
case 'H':pos--;break;
case 'P':pos++;break;
case 'I':pos-=p->maxview;break;
case 'Q':pos+=p->maxview;break;
}
if (pos<0) pos=0;
if (pos>=p->maxitems) pos=p->maxitems-1;
curLine=set_line_back(p->list,pos);
if (curLine>=p->topline+p->maxview) p->topline=curLine-p->maxview+1;
if (curLine<p->topline) p->topline=curLine;
}
while (save!=pos && p->list[pos]==NULL);
c_set_value(0,o->id,pos);
}
}
break;
}
case E_CONTROL:
{
int *q;
q=msg->data;
switch (*q++)
{
case 1:p->list=(TSTR_LIST)*q;
redraw_object(o);
break;
case 0:*(void **)*q=p->list;
break;
case 2:
i=get_to_topline(ls,p->topline,NULL);
if (*(int *)o->data<i) p->topline=set_line_back(ls,*(int *)o->data);
if (*(int *)o->data>=i+p->maxview) p->topline=set_line_back(ls,*(int *)o->data);
break;
}
}
case E_LOST_FOCUS:clicked=0;
}
}
void listbox(OBJREC *o)
{
o->datasize=sizeof(int);
o->runs[0]=string_list_init;
o->runs[1]=string_list_draw;
o->runs[2]=string_list_event;
//o->done=string_list_done;
}
/*void main()
{
TSTR_LIST test;
int i,j;
test=read_directory("c:\\windows\\system\\*.*",DIR_BREIF,_A_NORMAL);
j=str_count(test);
for(i=0;i<j;i++)
if (test[i]!=NULL) printf("%s\n",test[i]);
printf("%d souboru.\n",j);
release_list(test);
}
*/

9
libs/strlists.h Normal file
View file

@ -0,0 +1,9 @@
#define DIR_BREIF 1
#define DIR_SHORT 2
#define DIR_FULL 3
#define DIR_PATHLIST 4
#define DIR_DIRTREE 5
#define DIR_NAMES 6
void listbox(OBJREC *o);

404
libs/strlite.c Normal file
View file

@ -0,0 +1,404 @@
#include <skeldal_win.h>
#include "strlite.h"
#include <stdlib.h>
#include <stdio.h>
#include <mem.h>
#include <malloc.h>
#include <dos.h>
#include "types.h"
#include "memman.h"
TSTR_LIST create_list(int count)
{
register TSTR_LIST p;int i,j;
p=(TSTR_LIST)malloc(count*sizeof(*p));
if (p==NULL) return NULL;
j=_msize(p)/sizeof(*p);
for(i=0;i<j;i++) p[i]=NULL;
return p;
}
TSTR_LIST find_ptr(TSTR_LIST source,void *_ptr,int _size)
{
__asm
{
mov edi, source
mov eax, _ptr
mov ecx, _size
cld
repnz scasd
jnz skok
sub edi,4
skok:
mov eax, edi
}
}
//parm [edi][eax][ecx] value[edi];
const char *str_replace(TSTR_LIST *list,int line,const char *text)
{
int count,i,j;
TSTR_LIST p;
char *c;
count=str_count(*list);
if (line>=count)
{
int plus;
plus=count-line;
plus=(plus/STR_REALLOC_STEP+1)*STR_REALLOC_STEP;
p=getmem((count+plus)*sizeof(*p));
memcpy(p,*list,count*sizeof(*p));
free(*list);
j=_msize(p)/sizeof(*p);
i=count;
for(;i<j;i++) p[i]=NULL;
i=count;count=j;
*list=p;
}
if ((*list)[line]!=NULL) free((*list)[line]);
if (text!=NULL)
{
c=(char *)getmem(strlen(text)+1);
if (c==NULL) return NULL;
strcpy(c,text);
}
else
c=NULL;
(*list)[line]=c;
return c;
}
int str_add(TSTR_LIST *list,const char *text)
{
int count,i;
TSTR_LIST p;
count=str_count(*list);
p=find_ptr(*list,NULL,count);
i=p-*list;
str_replace(list,i,text);
return i;
}
const char *str_insline(TSTR_LIST *list,int before,const char *text)
{
int i,count,punkt;
TSTR_LIST p;
count=str_count(*list);
p=find_ptr(*list,NULL,count);
punkt=p-*list;
str_replace(list,punkt,NULL);
for(i=punkt;i>before;i--) (*list)[i]=(*list)[i-1];
(*list)[before]=NULL;
return str_replace(list,before,text);
}
void str_remove(TSTR_LIST *list,int line)
{
str_replace(list,line,NULL);
}
void str_delfreelines(TSTR_LIST *list)
{
int count,i,j;
TSTR_LIST p;
count=_msize(*list)/sizeof(*p);
j=0;
for(i=0;i<count;i++)
if ((*list)[i]!=NULL) (*list)[j++]=(*list)[i];
if (j==0) j++;
p=(TSTR_LIST)realloc(*list,j*sizeof(*p));
if (p!=NULL) *list=p;
count=_msize(*list)/sizeof(*p);
for(i=j;i<count;i++) (*list)[i]=NULL;
}
int str_count(TSTR_LIST p)
{
int count;
if (p==NULL) return 0;
count=_msize(p)/sizeof(*p);
return count;
}
void release_list(TSTR_LIST list)
{
int i,j;
if (list==NULL) return;
j=str_count(list);
for(i=0;i<j;i++)
str_remove(&list, i);
free(list);
}
typedef struct tuzel
{
char *data;
struct tuzel *levy,*pravy,*spatky;
}
TUZEL;
int sort_add_to_tree(TUZEL *uzel,const char *text, int dir)
{
TUZEL *q;
if (uzel->data==NULL)
{
uzel->data=text;
return 0;
}
q=(TUZEL *)getmem(sizeof(TUZEL));
if (q==NULL) return -1;
q->data=text;
q->levy=NULL;q->pravy=NULL;
while (uzel!=NULL)
if (strcmp(text,uzel->data)==dir)
{
if (uzel->levy==NULL)
{
uzel->levy=q;
q->spatky=uzel;
uzel=NULL;
}
else
uzel=uzel->levy;
}
else
{
if (uzel->pravy==NULL)
{
uzel->pravy=q;
q->spatky=uzel;
uzel=NULL;
}
else
uzel=uzel->pravy;
}
return 0;
}
void sort_read_list(TUZEL *uzel,TSTR_LIST list)
{
int counter=0;
TUZEL *ptr,*last;
int c;
if (uzel->data==NULL) return;
last=NULL;
while (uzel!=NULL)
{
if (last==NULL)
{
ptr=uzel;
uzel=uzel->levy;
last=NULL;
c=1;
}
else if (last==uzel->levy || (int)last==1)
{
ptr=uzel;
list[counter++]=uzel->data;
uzel=uzel->pravy;
last=NULL;
c=2;
}
else if (last==uzel->pravy || (int)last==2)
{
last=uzel;
uzel=uzel->spatky;
continue;
}
if (uzel==NULL)
{
last=(TUZEL *)c;
uzel=ptr;
}
}
}
void sort_release_tree(TUZEL *uzel)
{
TUZEL *ptr,*last;
int c;
if (uzel->data==NULL) return;
last=NULL;
while (uzel!=NULL)
{
if (last==NULL)
{
ptr=uzel;
uzel=uzel->levy;
last=NULL;
c=1;
}
else if (last==uzel->levy || (int)last==1)
{
ptr=uzel;
uzel=uzel->pravy;
last=NULL;
c=2;
}
else if (last==uzel->pravy || (int)last==2)
{
last=uzel;
uzel=uzel->spatky;
if (last->spatky!=NULL) free(last);
continue;
}
if (uzel==NULL)
{
last=(TUZEL *)c;
uzel=ptr;
}
}
}
TSTR_LIST sort_list(TSTR_LIST list,int direction)
{
TUZEL uz;
int i,j;
uz.data=NULL;uz.levy=NULL;uz.pravy=NULL;
uz.spatky=NULL;
j=str_count(list);
for(i=0;i<j;i++)
if (list[i]!=NULL) if (sort_add_to_tree(&uz,list[i],direction))
{
sort_release_tree(&uz);
return NULL;
}
sort_read_list(&uz,list);
sort_release_tree(&uz);
return list;
}
void pl_add_data(PTRMAP **p,void *data,int datasize)
{
PTRMAP *q;
q=(PTRMAP *)getmem(sizeof(PTRMAP));
q->data=(void *)getmem(datasize);
memcpy(q->data,data,datasize);
q->next=*p;
*p=q;
}
void pl_search(PTRMAP *p,void *key,int keysize,PTRMAP **find,PTRMAP **last)
{
*find=p;
*last=NULL;
while (*find!=NULL && memcmp((*find)->data,key,keysize)!=0)
{
*last=*find;
*find=(*find)->next;
}
}
void *pl_get_data(PTRMAP **p,void *key,int keysize)
{
PTRMAP *find, *last;
pl_search(*p,key,keysize,&find,&last);
if (find!=NULL) return find->data;
return NULL;
}
PTRMAP *pl_find_item(PTRMAP **p,void *key,int keysize)
{
PTRMAP *find,*last;
pl_search(*p,key,keysize,&find,&last);
return find;
}
void pl_delete_item(PTRMAP **p,void *key,int keysize)
{
PTRMAP *find,*last,*q;
pl_search(*p,key,keysize,&find,&last);
q=find;
if (q==NULL) return;
if (last==NULL) *p=find->next ;else last->next=find->next;
if (q->data!=NULL) free(q->data);
free(q);
}
void pl_delete_all(PTRMAP **p)
{
PTRMAP *q;
while (*p!=NULL)
{
q=*p;
*p=q->next;
if (q->data!=NULL) free(q->data);
free(q);
}
}
int load_string_list(TSTR_LIST *list,const char *filename)
{
char c[1024],*p;
int i,j,lin=0;
FILE *f;
f=fopen(filename,"r");
if (*list==NULL) *list=create_list(256);
if (f==NULL) return -1;
do
{
lin++;
do
{
j=fgetc(f);
if (j==';') while ((j=fgetc(f))!='\n' && j!=EOF);
if (j=='\n') lin++;
}
while (j=='\n');
ungetc(j,f);
j=fscanf(f,"%d",&i);
if (j==EOF)
{
fclose(f);
return -2;
}
if (j!=1)
{
fclose(f);
return lin;
}
if (i==-1) break;
while ((j=fgetc(f))<33 && j!=EOF);
if (j!=EOF) ungetc(j,f);
if (fgets(c,1022,f)==NULL)
{
fclose(f);
return lin;
}
p=strchr(c,'\n');if (p!=NULL) *p=0;
for(p=c;*p;p++) *p=*p=='|'?'\n':*p;
if (str_replace(list,i,c)==NULL)
{
fclose(f);
return -3;
}
}
while (1);
fclose(f);
return 0;
}
void strlist_cat(TSTR_LIST *org, TSTR_LIST add)
{
int cnt=str_count(add);
int i;
for (i=0;i<cnt;i++) str_add(org,add[i]);
}

35
libs/strlite.h Normal file
View file

@ -0,0 +1,35 @@
#ifndef _STRLITE_H_
#define _STRLITE_H_
typedef char **TSTR_LIST;
typedef struct ptrmap
{
struct ptrmap *next;
void *data;
}PTRMAP;
#define STR_REALLOC_STEP 256
TSTR_LIST create_list(int count);
int str_add(TSTR_LIST *list,const char *text);
const char *str_insline(TSTR_LIST *list,int before,const char *text);
const char *str_replace(TSTR_LIST *list,int line,const char *text);
void str_remove(TSTR_LIST *list,int line);
void str_delfreelines(TSTR_LIST *list);
int str_count(TSTR_LIST p);
void release_list(TSTR_LIST list);
TSTR_LIST sort_list(TSTR_LIST list,int direction);
TSTR_LIST read_directory(const char *mask,int view_type,int attrs);
void name_conv(const char *c);
void strlist_cat(TSTR_LIST *org, TSTR_LIST add);
void pl_add_data(PTRMAP **p,void *data,int datasize);
void *pl_get_data(PTRMAP **p,void *key,int keysize);
PTRMAP *pl_find_item(PTRMAP **p,void *key,int keysize);
void pl_delete_item(PTRMAP **p,void *key,int keysize);
void pl_delete_all(PTRMAP **p);
int load_string_list(TSTR_LIST *list,const char *filename);
#endif

150
libs/swaper.c Normal file
View file

@ -0,0 +1,150 @@
#include <stdio.h>
#define SWAP_FREE_LIST 8192
typedef struct sw_free_block
{
long size,seek;
}SW_FREE_BLOCK;
SW_FREE_BLOCK swp_list[SWAP_FREE_LIST];
int swp_ptr;
int swp_fnot_used=-1;
int swp_unuseds=0;
int swpl_overruns=0;
void swap_init(void)
{
swp_ptr=0;
swp_list[swp_ptr].seek=0;
swp_list[swp_ptr].size=-1;
swp_ptr=1;
}
int swap_find_block(long size)
{
int i;
SW_FREE_BLOCK *p;
p=swp_list;
for(i=0;i<swp_ptr;i++,p++)
if (p->size>=size) return i;
else if (p->seek==-1) swp_fnot_used=i;
return 0;
}
int swap_add_block(long size)
{
int i;
long sp;
SW_FREE_BLOCK *p;
size+=255;
size&=~255;
i=swap_find_block(size);
p=&swp_list[i];
sp=p->seek;
if (p->size==-1) p->seek+=size;
else if (p->size==size)
{
p->seek=-1;
p->size=-1;
swp_unuseds++;
swp_fnot_used=i;
}
else
{
p->seek+=size;
p->size-=size;
}
return sp;
}
void swap_find_seek(long seek1,long seek2,int *pos1,int *pos2)
{
int i;
SW_FREE_BLOCK *p;
p=swp_list;*pos1=-1;*pos2=-1;
for(i=0;i<swp_ptr;i++,p++)
{
if (p->seek==seek2)
{
*pos2=i;
if (*pos1>=0) return;
}
if (p->seek+p->size==seek1)
{
*pos1=i;
if (*pos2>=0) return;
}
}
}
void alloc_swp_block(long seek,long size)
{
if (swp_fnot_used<0 && swp_unuseds) swap_find_block(0x7fffffff);
if (swp_fnot_used<0)
{
swp_list[swp_ptr].seek=seek;
swp_list[swp_ptr].size=size;
swp_unuseds=0;
swp_ptr++;if (swp_ptr>=SWAP_FREE_LIST)
{
swpl_overruns++;
return;
}
}
else
{
swp_list[swp_fnot_used].seek=seek;
swp_list[swp_fnot_used].size=size;
swp_fnot_used=-1;
swp_unuseds--;
}
}
void swap_free_block(long seek,long size)
{
int i1,i2;
seek&=~255;
size+=255;
size&=~255;
swap_find_seek(seek,seek+size,&i1,&i2);
if (i2>=0 && i1>=0)
{
if (swp_list[i2].size!=-1) swp_list[i2].size+=swp_list[i1].size+size;
swp_list[i2].seek=swp_list[i1].seek;
swp_list[i1].seek=-1;
swp_list[i1].size=-1;
swp_unuseds++;swp_fnot_used=i1;
}
else if (i1>=0) swp_list[i1].size+=size;
else if (i2>=0)
{
if (swp_list[i2].size!=-1) swp_list[i2].size+=size;
swp_list[i2].seek=seek;
}
if (i1<0 && i2<0)
{
alloc_swp_block(seek,size);
}
}
/*main()
{
int i1,i2,i3,i4;
swap_init();
i1=swap_add_block(1024);
i2=swap_add_block(250);
i3=swap_add_block(1024);
i4=swap_add_block(1024);
swap_free_block(i1,1024);
swap_free_block(i3,1024);
swap_free_block(i2,250);
swap_free_block(i4,1024);
}
*/

90
libs/tasker.asm Normal file
View file

@ -0,0 +1,90 @@
.model small
.386
DGROUP group _DATA
extrn _tasklist_sp:dword[]
extrn _tasklist_low:dword[]
extrn _tasklist_top:dword[]
extrn _task_info:dword[]
extrn _curtask:dword
extrn _nexttask:dword
extrn _taskcount:dword
extrn __STACKLOW:dword
extrn __STACKTOP:dword
extrn _taskparam:dword
extrn free_:proc
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
public task_sleep_
task_sleep_:
mov _taskparam,eax
pushfd
pushad
mov eax,_curtask
mov esi,[_tasklist_sp]
mov edi,[_tasklist_low]
mov edx,[_tasklist_top]
mov ecx,[_task_info]
mov [esi+eax*4],esp
mov ebx,_nexttask
term_1: cmp eax,ebx
mov eax,ebx
jnz twake
xor eax,eax
taskloop:
inc ebx
cmp ebx,_taskcount
jc tasktest
xor ebx,ebx
tasktest:
cmp dword ptr [esi+ebx*4],0
jz taskloop
test byte ptr [ecx+ebx],2 ;test zda je task waiting
jnz taskloop ;ano - pak ho preskoc (task 0 nesmi byt waiting)
twake: mov _curtask,eax
mov _nexttask,ebx
mov esp,[esi+eax*4]
mov ebx,[edi+eax*4]
mov __STACKLOW,ebx
mov ebx,[edx+eax*4]
mov __STACKTOP,ebx
popad
popfd
mov eax,_taskparam
ret
public task_terminating_
task_terminating_:
;tato funkce je volana po kazdem ukonceni ulohy
mov eax,[_tasklist_sp]
mov esp,[eax]
mov ebx,[_tasklist_low]
mov ebx,[ebx]
mov __STACKLOW,ebx
mov ebx,[_tasklist_top]
mov ebx,[ebx]
mov __STACKTOP,ebx
mov eax,_curtask
mov esi,[_tasklist_low]
mov eax,[esi+4*eax]
call free_
mov eax,_curtask
xor ebx,ebx
mov esi,[_tasklist_sp]
mov [esi+4*eax],ebx
mov esi,[_tasklist_sp]
mov edi,[_tasklist_low]
mov edx,[_tasklist_top]
mov eax,_curtask
mov ebx,_nexttask
jmp term_1
_TEXT ends
end

148
libs/testsvga.c Normal file
View file

@ -0,0 +1,148 @@
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <vesa.h>
#include <i86.h>
#include "bgraph.h"
void *xlat;
static void help(void)
{
puts("\n"
"Tento program odtestuje grafickou kartu a rozhodne zda lze pouzit bez\n"
"dodatecne podpory ovladace UNIVESA ci UNIVBE.\n"
"\n"
"Program ma jednoduche ovladani: \n\n"
" Esc - pokud rezim nevyhovuje (nebo obrazovka je cerna ci plna nesmyslu)\n"
" Enter - pokud rezim vyhovuje.\n"
"\n"
"Z dosavadnich pokusu se ukazuje ze program muze mit problemy na kartach rady\n"
"CIRRUS LOGIC a klony\n"
"\n"
"Stiskni ENTER a zacneme."
);
getchar();
}
extern word sada7;
#define TEXT_OK "Stiskni ENTER pokud reim vyhovuje"
void testovaci_obrazec(char *name)
{
int i,j,k,x,y,c;
curcolor=0;
bar(0,0,639,479);
rectangle(0,0,639,479,0x7fff);
line(0,0,639,479);
line(0,479,639,0);
x=20,y=20;
for(k=0;k<7;k++)
{
for(i=0;i<64;i++)
for(j=0;j<64;j++)
{
switch (k)
{
case 0:c=(i>>1)+((j>>1)<<5);break;
case 1:c=(i>>1)+((j>>1)<<10);break;
case 2:c=((i>>1)<<5)+((j>>1)<<10);break;
case 3:c=(i>>1)+((j>>1)<<5)+0x7c00;break;
case 4:c=(i>>1)+((j>>1)<<10)+0x03e0;break;
case 5:c=((i>>1)<<5)+((j>>1)<<10)+0x001f;break;
case 6:c=(i+j)>>2;c=(c<<10)+(c<<5)+c;break;
}
point(x+i,y+j,c);
}
x+=100;
if (x>300) {y+=100;x=20;}
}
curfont=&sada7;
set_aligned_position(320,400,1,0,name);
outtext(name);
set_aligned_position(320,420,1,0,TEXT_OK);
outtext(TEXT_OK);
showview(0,0,0,0);
}
void write_error(int error,char *rezim)
{
switch (error)
{
case -1: printf("Graficky rezim karta nepodporuje (%s)\n",rezim);break;
case -10: printf("Rezim nepodporuje zmenu scanovaci radky (%s)\n",rezim);break;
}
puts("\n Stiskni cokoliv a budem pokracovat");
}
void snd(int freq)
{
sound(freq);
delay(100);
nosound();
}
int test_hicolor_1(void)
{
int error;
error=initmode32();
if (error)
{
closemode();
write_error(error,"Hicolor");
return error;
}
testovaci_obrazec("640 x 480 x 32768 barev");
snd(100);
while (kbhit()) getche();
error=getche()==27;
snd(1000);
closemode();
return error;
}
int test_palcolor_1(void)
{
int error;
error=initmode256(xlat);
if (error)
{
closemode();
write_error(error,"256 barev");
return error;
}
testovaci_obrazec("640 x 480 x 256 barev / rastrovani / paleta 5,6,5");
snd(100);
while (kbhit()) getche();
error=getche()==27;
snd(1000);
closemode();
return error;
}
main()
{
char ok1,ok2;
xlat=create_special_palette();
help();
ok1=test_hicolor_1();
ok2=test_palcolor_1();
if (ok1 && ok2)
{
puts("Hru 'Brany Skeldalu' nelze provozovat na teto karte bez ovladace");
}
else
{
if (!ok1) puts("Graficka karta JE kompatibilni s VESA 1.2");
if (!ok2) puts("Graficka karta JE kompatibilni s VESA 1.0.");
puts("Hru lze spustit bez univerzalniho ovladace");
}
puts("\n"
"Dotazy na e-mail: xnovako1@cs.felk.cvut.cz");
}

6
libs/tst.c Normal file
View file

@ -0,0 +1,6 @@
main()
{
printf("%08X\n",102533234);
getchar();
return 0;
}

4
libs/types.h Normal file
View file

@ -0,0 +1,4 @@
#define byte char
#define integer signed short
#define word unsigned short
#define longint long

98
libs/vesatst.c Normal file
View file

@ -0,0 +1,98 @@
#include "types.h"
#include <vesa.h>
#include <dpmi.h>
#include <stdio.h>
#include <malloc.h>
#include "bgraph.h"
#include <i86.h>
MODEinfo vesadata;
word lastbank=0;
word *mapvesaadr(word *a);
#pragma aux mapvesaadr parm [edi] value [edi]
void showview32b(word x,word y,word xs,word ys)
{
register longint a;
if (x>640 || y>480) return;
if (xs==0) xs=640;
if (ys==0) ys=480;
if (x+xs>640) xs=640-x;
if (y+ys>480) ys=480-y;
if (xs>550 && ys>400)
{
redraw32b(screen,lbuffer,NULL);
return;
}
a=(x<<1)+linelen*y;
redrawbox32b(xs,ys,(void *)((char *)screen+a),(void *)a);
}
int initmode32b()
{
getmodeinfo(&vesadata,0x110);
if (!(vesadata.modeattr & MA_SUPP)) return -1;
setvesamode(0x110,-1);
lbuffer=(word *)0xa0000;
screen=lbuffer;
linelen=640*2;
showview=showview32b;
screen=(void *)malloc(screen_buffer_size);
return 0;
}
word *mapvesaadr1(word *a)
{
word bank;
bank=(long)a>>16;
if (bank!=lastbank)
{
lastbank=bank;
bank=bank;
{
union REGS regs;
regs.w.ax = 0x4f05;
regs.w.bx = 0;
regs.w.dx = bank;
int386 (0x10,&regs,&regs); // window A
}
}
return (word *)(((long)a & 0xffff)+0xa0000);
}
void switchvesabank(word bank)
#pragma aux switchvesabank parm [eax]
{
union REGS regs;
regs.w.ax = 0x4f05;
regs.w.bx = 0;
regs.w.dx = bank;
int386 (0x10,&regs,&regs); // window A
}
void vesatst()
{
int i,j;
word *a;
a=screen;
for (i=0;i<480;i++)
for(j=i;j<i+640;j++)
*(a++)=i+j;
showview(10,10,400,300);
}
void main()
{
initmode32b();
getchar();
vesatst();
getchar();
}

42
libs/wav.c Normal file
View file

@ -0,0 +1,42 @@
#include <skeldal_win.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "WAV.H"
int find_chunk(FILE *riff,char *name)
{
char chunk_name[4];
long next;
fseek(riff,12,SEEK_SET);
do
{
fread(chunk_name,1,4,riff);
if (!strncmp(name,chunk_name,4)) return ftell(riff);
if (fread(&next,1,4,riff)==0) return -1 ;
if (fseek(riff,next,SEEK_CUR))return -1 ;
}
while (!feof(riff));
return -1;
}
int get_chunk_size(FILE *riff)
{
long size;
fread(&size,1,4,riff);
fseek(riff,-4,SEEK_CUR);
return(size);
}
int read_chunk(FILE *riff,void *mem)
{
long size,res;
fread(&size,1,4,riff);
res=fread(mem,1,size,riff);
return res==size;
}

20
libs/wav.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef _WAV_H
#define _WAV_H
#define WAV_RIFF "RIFF"
#define WAV_WAVE "WAVE"
#define WAV_FMT "fmt "
#define WAV_DATA "data"
typedef struct t_wave
{
unsigned short wav_mode,chans;
long freq,bps;
}T_WAVE;
int find_chunk(FILE *riff,char *name); //-1 neuspech, jinak pozice
int get_chunk_size(FILE *riff); //velikost
int read_chunk(FILE *riff,void *mem); // 1 neuspech
#endif

37
libs/wav_mem.c Normal file
View file

@ -0,0 +1,37 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "WAV_MEM.H"
char *find_chunk(char *wav,char *name)
{
long next;
wav+=12;
do
{
if (!strncmp(name,wav,4)) return wav+4;
wav+=4;
memcpy(&next,wav,4);
wav+=next+4;
}
while (1);
}
int get_chunk_size(char *wav)
{
long size;
memcpy(&size,wav,4);
return(size);
}
int read_chunk(char *wav,void *mem)
{
wav+=4;
memcpy(mem,wav,get_chunk_size(wav-4));
return 0;
}

20
libs/wav_mem.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef _WAV_H
#define _WAV_H
#define WAV_RIFF "RIFF"
#define WAV_WAVE "WAVE"
#define WAV_FMT "fmt "
#define WAV_DATA "data"
typedef struct t_wave
{
unsigned short wav_mode,chans;
long freq,bps;
}T_WAVE;
char *find_chunk(char *wav,char *name);
int get_chunk_size(char *wav);
int read_chunk(char *wav,void *mem);
#endif

1426
libs/zvuk.c Normal file

File diff suppressed because it is too large Load diff

74
libs/zvuk.h Normal file
View file

@ -0,0 +1,74 @@
#ifndef __ZVUK_H___
#define __ZVUK_H___
#ifdef __cplusplus
extern "C" {
#endif
#define BACK_BUFF_SIZE 0x40000
#define DEV_NOSOUND 0
#define DEV_SB10 1
#define DEV_SB20 2
#define DEV_SBPRO 3
#define DEV_SB16 4
#define DEV_WSS 5
#define DEV_ULTRA 6
#define DEV_DAC 7
#define DEV_PCSPEAKER 8
#define DEV_DIRECTSOUND 9 //only valid device for this module
extern int bvolume;
extern void (*konec_skladby)(char **jmeno);
int sound_detect(int *dev,int *port,int *dma, int *irq);
void set_mixing_device(int mix_dev,int mix_freq,...);
char start_mixing();
void stop_mixing();
void play_sample(int channel,void *sample,long size,long lstart,long sfreq,int type);
void set_channel_volume(int channel,int left,int right);
void init_winamp_plugins(const char *path);
void fade_music();
int mix_back_sound(int synchro);
int open_backsound(char *filename);
void change_music(const char *filename);
int get_timer_value();
char *device_name(int device);
void force_music_volume(int volume);
void set_backsnd_freq(int freq);
char get_channel_state(int channel);
void get_channel_volume(int channel,int *left,int *right);
void mute_channel(int channel);
void chan_break_loop(int channel);
void chan_break_ext(int channel,void *org_sample,long size_sample); //zrusi loop s moznosti dohrat zvuk
char set_snd_effect(int funct,int data);
char check_snd_effect(int funct);
int get_snd_effect(int funct);
void *PrepareVideoSound(int mixfreq, int buffsize);
char LoadNextVideoFrame(void *buffer, char *data, int size, short *xlat, short *accnums, long *writepos);
void DoneVideoSound(void *buffer);
#define SND_MAXFUNCT 11
#define SND_PING 0 //Ping function
#define SND_GVOLUME 1 //SetGlobalVolume
#define SND_BASS 2 //SetBass
#define SND_TREBL 3 //SetTrebles
#define SND_SWAP 4 //SetSwapChannels
#define SND_LSWAP 5 //SetLinearSwapping
#define SND_SURROUND 6 //Surrourd
#define SND_OUTFILTER 7//Out Filter
#define SND_GFX 8 //setgfxvolume
#define SND_MUSIC 9 //setmusicvolume
#define SND_XBASS 10 //setxbassy
#ifdef __cplusplus
}
#endif
#endif

842
libs/zvuk_dx.cpp Normal file
View file

@ -0,0 +1,842 @@
#define INITGUID
#include <skeldal_win.h>
#include <malloc.h>
#include <debug.h>
#include <stdio.h>
#define DWORD_PTR DWORD *
#include <dsound.h>
#include "types.h"
#include "zvuk.h"
#include <math.h>
extern "C" {
#include <memman.h>
}
#define MAXCHANNELS 32
#define TIMEIDLESTOPCHANNEL 250
#define DEFAULTBUFFERSIZE (256*1024)
#define FADELENGTH 3000
#define MUS_ERRORWAIT 5000
#include "Music.h"
static int cur_device=0;
static int cur_mixfreq=0;
static bool swap_chans=false;
class CheckRes
{
public:
HRESULT operator=(HRESULT other)
{
if (other==0) return 0;
char buff[256];
sprintf(buff,"DirectSound error HRESULT %08X, code %d",other,other & 0xFFFF);
int id=MessageBox(NULL,buff,NULL,MB_SYSTEMMODAL|MB_ABORTRETRYIGNORE);
if (id==IDRETRY)
{
__asm int 3;
return other;
}
if (id==IDIGNORE) return other;
exit(-1);
}
};
static CheckRes hres;
static HWND hWndDS8=NULL;
static IDirectSound8 *ds8=NULL;
static IDirectSoundBuffer *ds_primary;
static WAVEFORMATEX waveformat;
static int gfx_volume=255;
static int music_volume=127;
static int glob_volume=255;
static int linvoltable[256];
static MusicPlayer GMusicPlayer;
static MusDecoder GMusDecoder;
static WinAmpDecoder GWinAmpPlayer;
static IDecoder *GCurrentDecoder=&GMusDecoder;
class SoundChannelInfo
{
public:
CRITICAL_SECTION sect;
char *play_pos, *start_loop, *end_loop;
IDirectSoundBuffer8 *buffer;
unsigned long chantype;
unsigned long idsPlayPos;
unsigned long idsWritePos;
unsigned long idsBuffSize;
long volume; //volume for DS
long pan; //pan for DS
int volleft; //left volume for skeldal
int volright; //right volume for skeldal
unsigned long preload;
unsigned long stopTime; //time, when buffer reached end. For calculating idle time
unsigned long startTime; //time, when buffer started. For calculating idle time, use 0 to sticky buffer
SoundChannelInfo()
{
buffer=NULL;
play_pos=start_loop=end_loop=NULL;
InitializeCriticalSection(&sect);
pan=DSBPAN_CENTER;
volume=DSBVOLUME_MAX;
}
~SoundChannelInfo() {if (buffer) buffer->Release();DeleteCriticalSection(&sect);}
unsigned long CalculateLockSize();
void ChannelMaintaince();
bool IsPlaying() {return play_pos!=NULL;}
// bool IsFree(char type) {return play_pos==NULL || (type==chantype && play_pos==end_loop);}
void Reset();
void InitChannel(char type, char *ppos, char *bloop,char *eloop, int freq);
void Lock() {EnterCriticalSection(&sect);}
void Unlock() {LeaveCriticalSection(&sect);}
bool TryLock() {return TryEnterCriticalSection(&sect)!=FALSE;}
void SetVolume(long vol)
{
Lock();
if (volume!=vol) if (buffer && play_pos ) hres=buffer->SetVolume(vol);
volume=vol;
Unlock();
}
void SetPan(long p)
{
Lock();
if (pan!=p) if (buffer && play_pos ) hres=buffer->SetPan(p);
pan=p;
Unlock();
}
void Mute()
{
Lock();
Stop();
Unlock();
}
void Stop()
{
if (buffer)
buffer->Stop();
play_pos=NULL;
}
void BreakLoop() {start_loop=end_loop;}
void BreakLoopEx(char *end_sample) {start_loop=end_loop=end_sample;}
};
static bool shutMaintaince=false;
static SoundChannelInfo channels[MAXCHANNELS];
static HANDLE maintainceThread;
ULONG __stdcall MaintainceThread(void *);
static void DSStart(int mixfreq)
{
DSBUFFERDESC desc;
for (int i=1;i<256;i++)
{
double rang=pow(i/255.0,15);
linvoltable[i]=100*log(rang);
}
linvoltable[0]=-10000;
hres=DirectSoundCreate8(&DSDEVID_DefaultPlayback,&ds8,NULL);
if (hWndDS8) hres=ds8->SetCooperativeLevel(hWndDS8,DSSCL_PRIORITY);
memset(&desc,0,sizeof(desc));
desc.dwSize=sizeof(desc);
desc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
hres=ds8->CreateSoundBuffer(&desc,&ds_primary,NULL);
waveformat.cbSize=sizeof(waveformat);
waveformat.nBlockAlign=4;
waveformat.nChannels=2;
waveformat.nSamplesPerSec=mixfreq;
waveformat.nAvgBytesPerSec=mixfreq*4;
waveformat.wBitsPerSample=16;
waveformat.wFormatTag=WAVE_FORMAT_PCM;
hres=ds_primary->SetFormat(&waveformat);
DWORD id;
shutMaintaince=false;
maintainceThread=CreateThread(NULL,0,MaintainceThread,NULL,0,&id);
SetThreadPriority(maintainceThread,THREAD_PRIORITY_HIGHEST);
GMusicPlayer.InitBuffer(ds8,linvoltable);
GMusicPlayer.Play();
}
void init_winamp_plugins(const char *path)
{
GWinAmpPlayer.LoadPlugins(path);
}
static void DSStop()
{
GCurrentDecoder->Stop();
GMusDecoder.Stop();
GMusicPlayer.Done();
GWinAmpPlayer.ClearList();
shutMaintaince=true;
WaitForSingleObject(maintainceThread,INFINITE);
CloseHandle(maintainceThread);
for (int i=0;i<MAXCHANNELS;i++)
if (channels[i].buffer)
{channels[i].Stop(); channels[i].buffer->Release();channels[i].buffer=NULL;}
if (ds_primary) ds_primary->Release();
ds_primary=NULL;
if (ds8) ds8->Release();
ds8=NULL;
}
unsigned long SoundChannelInfo::CalculateLockSize()
{
if (buffer==NULL) return 0;
unsigned long playpos;
buffer->GetCurrentPosition(NULL,&playpos);
long diff=(signed)playpos-(signed)idsPlayPos;
if (diff<0) diff+=idsBuffSize;
unsigned long wendpos=playpos+preload;
if (wendpos>=idsBuffSize) wendpos-=idsBuffSize;
if (wendpos<idsWritePos && wendpos>playpos) return 0;
if (wendpos<idsWritePos) wendpos+=idsBuffSize;
unsigned long sz=(wendpos-idsWritePos+3) & ~3;
if (sz>idsBuffSize/2) sz=idsBuffSize/2;
idsPlayPos=playpos;
return sz;
}
void SoundChannelInfo::ChannelMaintaince()
{
Lock();
if (play_pos!=NULL)
{
if (play_pos!=end_loop) stopTime=GetTickCount();
unsigned long lockSize=CalculateLockSize();
if (lockSize)
{
// printf("%8d\r",lockSize);
void *audioptrs[2];
unsigned long sizes[2];
hres=buffer->Lock(idsWritePos,lockSize,audioptrs,sizes,audioptrs+1,sizes+1,0);
for (int i=0;i<2 && audioptrs[i];i++)
{
char *wrt=(char *)audioptrs[i];
for (unsigned long j=0;j<sizes[i];j++) if (play_pos!=end_loop)
{
*wrt++=*play_pos++;
if (play_pos==end_loop) play_pos=start_loop;
}
else
{
if (chantype & 0x1) *wrt++=0x80; else *wrt++=0;
}
}
hres=buffer->Unlock(audioptrs[0],sizes[0],audioptrs[1],sizes[1]);
idsWritePos+=lockSize;
if (idsWritePos>=idsBuffSize) idsWritePos-=idsBuffSize;
}
if (play_pos==end_loop && GetTickCount()-stopTime>TIMEIDLESTOPCHANNEL)
{
Stop();
}
}
Unlock();
}
static void MixMaintaince()
{
for (int i=0;i<MAXCHANNELS;i++) channels[i].ChannelMaintaince();
}
static ULONG __stdcall MaintainceThread(void *)
{
while (!shutMaintaince) {MixMaintaince();Sleep(50);}
return 0;
}
void SoundChannelInfo::Reset()
{
Lock();
if (buffer) buffer->Release();
buffer=NULL;
Unlock();
}
void SoundChannelInfo::InitChannel(char type, char *ppos, char *bloop,char *eloop, int freq)
{
Lock();
unsigned long newchantype=type+freq*4;
if (chantype!=newchantype || buffer==NULL)
{
Reset();
DSBUFFERDESC desc;
WAVEFORMATEX wfex;
wfex.cbSize=sizeof(wfex);
wfex.wFormatTag=WAVE_FORMAT_PCM;
wfex.wBitsPerSample=type==1?8:16;
wfex.nSamplesPerSec=freq;
wfex.nChannels=1;
wfex.nBlockAlign=type==1?1:2;
wfex.nAvgBytesPerSec=wfex.nBlockAlign*wfex.nSamplesPerSec;
memset(&desc,0,sizeof(desc));
desc.dwSize=sizeof(desc);
desc.dwFlags=DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME|DSBCAPS_GETCURRENTPOSITION2;
desc.dwBufferBytes=DEFAULTBUFFERSIZE;
desc.lpwfxFormat=&wfex;
preload=wfex.nAvgBytesPerSec/5;
IDirectSoundBuffer *bufold;
hres=ds8->CreateSoundBuffer(&desc,&bufold,NULL);
hres=bufold->QueryInterface(IID_IDirectSoundBuffer8,(void **)&buffer);
bufold->Release();
idsPlayPos=DEFAULTBUFFERSIZE-cur_mixfreq;
idsWritePos=0;
idsBuffSize=DEFAULTBUFFERSIZE;
play_pos=ppos;
start_loop=bloop;
end_loop=eloop;
chantype=newchantype;
hres=buffer->SetVolume(volume);
hres=buffer->SetPan(pan);
ChannelMaintaince();
hres=buffer->Play(0,0,DSBPLAY_LOOPING);
stopTime=startTime=GetTickCount();
}
else
{
buffer->Stop();
idsBuffSize=DEFAULTBUFFERSIZE;
buffer->SetCurrentPosition(0);
buffer->GetCurrentPosition(&idsPlayPos,&idsWritePos);
hres=buffer->SetVolume(volume);
hres=buffer->SetPan(pan);
play_pos=ppos;
start_loop=bloop;
end_loop=eloop;
ChannelMaintaince();
buffer->Play(0,0,DSBPLAY_LOOPING);
stopTime=startTime=GetTickCount();
}
Unlock();
}
/*
static int FindFreeChannel(char type)
{
int older=0;
DWORD m_age=0;
DWORD timval=GetTickCount();
for (int i=0;i<MAXCHANNELS;i++) if (!channels[i].IsFree(char type)) return i;
{
DWORD age==timval-channels[i].startTime;
if (age>m_age) {older=i;m_age=age;}
}
return older;
}
*/
extern "C"
{
int bvolume; //background volume
void (*konec_skladby)(char **jmeno)=NULL; //pointer to function to notify that end of song has been reached
void DSReportWindowCreation(HWND hWindow)
{
hWndDS8=hWindow;
if (ds8!=NULL) hres=ds8->SetCooperativeLevel(hWndDS8,DSSCL_PRIORITY);
}
int sound_detect(int *dev,int *port,int *dma, int *irq)
{
*dev=DEV_DIRECTSOUND;
*port=0;
*dma=0;
*irq=0;
return 0;
}
void set_mixing_device(int mix_dev,int mix_freq,...)
{
cur_device=mix_dev;
cur_mixfreq=mix_freq;
}
char start_mixing()
{
if (cur_device!=DEV_DIRECTSOUND)
{
MessageBox(hWndDS8,"Invalid sound device! Check SKELDAL.INI. Only device 9 (DirectSound) can be used.",NULL,MB_SYSTEMMODAL);
exit(1);
}
if (cur_mixfreq==0) return FALSE;
DSStart(cur_mixfreq);
return TRUE;
}
void stop_mixing()
{
DSStop();
}
void play_sample(int channel,void *sample,long size,long lstart,long sfreq,int type)
{
char *start=(char *)sample;
channels[channel].InitChannel(type,start,start+lstart,start+size,sfreq);
}
void set_channel_volume(int channel,int left,int right)
{
if (left>32767) left=32767;
if (left<0) left=0;
if (right>32767) right=32767;
if (right<0) right=0;
int volleft=linvoltable[(left>>7)*gfx_volume/255];
int volright=linvoltable[(right>>7)*gfx_volume/255];
int volsum=__max(volleft,volright);
channels[channel].SetVolume(volsum);
channels[channel].SetPan(swap_chans?(volright-volleft):(volleft-volright));
channels[channel].volleft=left;
channels[channel].volright=right;
}
char get_channel_state(int channel)
{
return channels[channel].IsPlaying()==true;
}
void get_channel_volume(int channel,int *left,int *right)
{
if (left) *left=channels[channel].volleft;
if (right) *right=channels[channel].volright;
}
void mute_channel(int channel)
{
channels[channel].Mute();
}
void chan_break_loop(int channel)
{
channels[channel].BreakLoop();
}
void chan_break_ext(int channel,void *org_sample,long size_sample) //zrusi loop s moznosti dohrat zvu
{
char *end_sample=(char *)org_sample+size_sample;
channels[channel].BreakLoopEx(end_sample);
}
char set_snd_effect(int funct,int data)
{
switch (funct)
{
case SND_PING: return 1;
case SND_SWAP: swap_chans=(data & 1)!=0;return 1;
case SND_GFX: gfx_volume=data;return 1;
case SND_MUSIC: GCurrentDecoder->SetVolume(music_volume=data,get_snd_effect(SND_GVOLUME));return 1;
case SND_GVOLUME: hres=ds_primary->SetVolume(linvoltable[glob_volume=data]);return 1;
default: return 0;
}
}
int get_snd_effect(int funct)
{
switch (funct)
{
case SND_PING: return 1;
case SND_SWAP: return swap_chans;
case SND_GFX: return gfx_volume;
case SND_MUSIC: return music_volume;
case SND_GVOLUME: return glob_volume;
default: return 0;
}
}
char check_snd_effect(int funct)
{
switch (funct)
{
case SND_PING:
case SND_SWAP:
case SND_MUSIC:
case SND_GVOLUME:
case SND_GFX: return 1;
default: return 0;
}
}
static DWORD Mus_buffSize;
/*
static HANDLE music_file=NULL;
static HANDLE next_music_file=NULL;
static bool fading=false;
static DWORD fadetime;
static DWORD Mus_lastWritePos;
static DWORD Mus_nextBlockSize;
static DWORD Mus_nextBlockRead;
static DWORD Mus_errorWait=0;
static DWORD Mus_silentPlay=0;
#pragma pack (1)
struct MusFile
{
short channels;
long freq;
long ssize;
long blocks;
long reserved1;
long reserved2;
short ampltable[256];
};
static MusFile curMus;
#pragma pack()
static char OpenMus(HANDLE music_file)
{
DWORD bytesread;
SetFilePointer(music_file,0,NULL,FILE_BEGIN);
if (ReadFile(music_file,&curMus,sizeof(curMus),&bytesread,NULL)==TRUE && bytesread==sizeof(curMus))
{
if (ReadFile(music_file,&Mus_nextBlockRead,sizeof(Mus_nextBlockRead),&bytesread,NULL)==FALSE) return 0;
if (ReadFile(music_file,&Mus_nextBlockSize,sizeof(Mus_nextBlockSize),&bytesread,NULL)==FALSE) return 0;
if (ds_music!=NULL) ds_music->Release();
WAVEFORMATEX wfex;
wfex.cbSize=sizeof(wfex);
wfex.wBitsPerSample=16;
wfex.nBlockAlign=2*curMus.channels;
wfex.nSamplesPerSec=curMus.freq;
wfex.nAvgBytesPerSec=curMus.freq*wfex.nBlockAlign;
wfex.wFormatTag=WAVE_FORMAT_PCM;
wfex.nChannels=curMus.channels;
DSBUFFERDESC desc;
desc.dwSize=sizeof(desc);
desc.dwBufferBytes=Mus_buffSize=wfex.nAvgBytesPerSec*4;
desc.dwReserved=0;
desc.dwFlags=DSBCAPS_CTRLVOLUME ;
desc.lpwfxFormat=&wfex;
IDirectSoundBuffer *dsbf;
hres=ds8->CreateSoundBuffer(&desc,&dsbf,NULL);
hres=dsbf->QueryInterface(IID_IDirectSoundBuffer8,(void **)&ds_music);
dsbf->Release();
void *ptr;
DWORD size;
ds_music->Lock(0,0,&ptr,&size,NULL,NULL,DSBLOCK_ENTIREBUFFER);
memset(ptr,0,size);
ds_music->Unlock(ptr,size,NULL,NULL);
ds_music->SetVolume(linvoltable[music_volume]);
ds_music->Play(0,0,DSBPLAY_LOOPING);
fadetime=0;
Mus_lastWritePos=wfex.nAvgBytesPerSec;
Mus_silentPlay=0;
return 1;
}
return 0;
}
static void PrepareMusFile(const char *filename)
{
CloseHandle(next_music_file);
next_music_file=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if (next_music_file==INVALID_HANDLE_VALUE)
next_music_file=NULL;
}
static char music_decompres_block()
{
DWORD bytesread;
char *data=(char *)alloca(Mus_nextBlockRead);
short accum[2]={0,0};
char curchan=0;
DWORD lockSizes[2];
void *lockPtrs[2];
if (ReadFile(music_file,data,Mus_nextBlockRead,&bytesread,NULL)==FALSE) return 0;
ds_music->Lock(Mus_lastWritePos,Mus_nextBlockSize,lockPtrs,lockSizes,lockPtrs+1,lockSizes+1,0);
for (int j=0;j<2;j++)
{
short *target=(short *)lockPtrs[j];
for (DWORD i=0;i<lockSizes[j];i+=2)
{
short val=accum[curchan]+curMus.ampltable[*data++];
accum[curchan]=val;
if (data[-1]==0) //pridano jako provizorni reseni pro korekci chyby komprimacniho programu
{
val-=31767;
}
if (fadetime)
{
long ftime=FADELENGTH-(GetTickCount()-fadetime);
if (ftime<0) ftime=0;
float mul=(float)ftime*(float)ftime/(float)(FADELENGTH*FADELENGTH);
val=(short)(val*mul);
}
*target++=val;
curchan++;
if (curchan>=curMus.channels) curchan=0;
}
}
ds_music->Unlock(lockPtrs[0],lockSizes[0],lockPtrs[1],lockSizes[1]);
Mus_lastWritePos+=Mus_nextBlockSize;
if (Mus_lastWritePos>=Mus_buffSize) Mus_lastWritePos-=Mus_buffSize;
return 1;
}
static char music_silent_play()
{
DWORD lockSizes[2];
void *lockPtrs[2];
ds_music->Lock(Mus_lastWritePos,Mus_nextBlockSize,lockPtrs,lockSizes,lockPtrs+1,lockSizes+1,0);
for (int j=0;j<2;j++)
{
short *target=(short *)lockPtrs[j];
for (DWORD i=0;i<lockSizes[j];i+=2)
{
*target++=0;
}
}
ds_music->Unlock(lockPtrs[0],lockSizes[0],lockPtrs[1],lockSizes[1]);
Mus_lastWritePos+=Mus_nextBlockSize;
if (Mus_lastWritePos>=Mus_buffSize) Mus_lastWritePos-=Mus_buffSize;
return 1;
}
void fade_music()
{
if (fadetime==0) fadetime=music_file?GetTickCount():0;
}
static int mix_back_sound_worker()
{
DWORD bytesread;
if (music_file==NULL) return -2;
if (ds_music==NULL)
if (OpenMus(music_file)==0) return -2;
DWORD play;
ds_music->GetCurrentPosition(&play,NULL);
while (true)
{
if (Mus_lastWritePos<=play)
{
if (Mus_lastWritePos+Mus_nextBlockSize>=play) return 0;
}
else
{
if (Mus_lastWritePos+Mus_nextBlockSize>play+Mus_buffSize) return 0;
}
if (Mus_silentPlay)
{
if (Mus_silentPlay>GetTickCount())
{
music_silent_play();
return 0;
}
else
return -2;
}
if (music_decompres_block()==0) return -2;
curMus.blocks--;
if (curMus.blocks<0)
{
Mus_silentPlay=GetTickCount()+4000;
return 0;
}
if (ReadFile(music_file,&Mus_nextBlockRead,sizeof(Mus_nextBlockRead),&bytesread,NULL)==FALSE) return -2;
if (ReadFile(music_file,&Mus_nextBlockSize,sizeof(Mus_nextBlockSize),&bytesread,NULL)==FALSE) return -2;
if (fadetime && fadetime+FADELENGTH<GetTickCount())
{
Mus_silentPlay=GetTickCount()+4000;
return 0;
}
}
Mus_errorWait=0;
return 0;
}
*/
int mix_back_sound(int synchro)
{
if (GCurrentDecoder->IsPlaying()) return 0;
char *next_music;
konec_skladby(&next_music);
change_music(next_music);
return 0;
}
void change_music(const char *mus_filename)
{
if (GCurrentDecoder->NotUsingOutput()) GMusDecoder.Stop();
GCurrentDecoder->Stop();
if (mus_filename==0)
{
mus_filename="?";
GCurrentDecoder=&GMusDecoder;
}
else
{
const char *c=strrchr(mus_filename,'.');
if (c!=0 && stricmp(c,".mus")==0)
GCurrentDecoder=&GMusDecoder;
else
GCurrentDecoder=&GWinAmpPlayer;
}
GCurrentDecoder->AttachOutput(&GMusicPlayer);
if (GCurrentDecoder->Play(mus_filename)==false) change_music(0);
GCurrentDecoder->SetVolume(music_volume,get_snd_effect(SND_GVOLUME));
if (GCurrentDecoder->NotUsingOutput())
GMusDecoder.Play("?");
}
int get_timer_value()
{
return GetTickCount()/TIMERSPEED
}
char *device_name(int device)
{
if (device!=DEV_DIRECTSOUND) return "Unknown device!";
else return "DirectSound 8";
}
void force_music_volume(int volume)
{
}
void set_backsnd_freq(int bfreq)
{
}
void *PrepareVideoSound(int mixfreq, int buffsize)
{
WAVEFORMATEX wfex;
wfex.cbSize=sizeof(wfex);
wfex.wBitsPerSample=16;
wfex.nBlockAlign=4;
wfex.nSamplesPerSec=mixfreq;
wfex.nAvgBytesPerSec=mixfreq*wfex.nBlockAlign;
wfex.wFormatTag=WAVE_FORMAT_PCM;
wfex.nChannels=2;
DSBUFFERDESC desc;
desc.dwSize=sizeof(desc);
desc.dwBufferBytes=Mus_buffSize=buffsize;
desc.dwReserved=0;
desc.dwFlags=DSBCAPS_CTRLVOLUME ;
desc.lpwfxFormat=&wfex;
IDirectSoundBuffer *dsbf;
IDirectSoundBuffer8 *ds_music;
hres=ds8->CreateSoundBuffer(&desc,&dsbf,NULL);
hres=dsbf->QueryInterface(IID_IDirectSoundBuffer8,(void **)&ds_music);
dsbf->Release();
void *ptr;
DWORD size;
ds_music->Lock(0,0,&ptr,&size,NULL,NULL,DSBLOCK_ENTIREBUFFER);
memset(ptr,0,size);
ds_music->Unlock(ptr,size,NULL,NULL);
ds_music->SetVolume(0);
ds_music->Play(0,0,DSBPLAY_LOOPING);
return (void *)ds_music;
}
char LoadNextVideoFrame(void *buffer, char *data, int size, short *xlat,short *accnums, long *writepos)
{
IDirectSoundBuffer8 *ds_music=(IDirectSoundBuffer8 *)buffer;
DSBCAPS caps;
caps.dwSize=sizeof(caps);
ds_music->GetCaps(&caps);
DWORD play;
ds_music->GetCurrentPosition(&play,NULL);
long remain=play-*writepos;
if (remain<0) remain+=caps.dwBufferBytes;
if (remain<size*2) return 0;
char curchan=0;
DWORD lockSizes[2];
void *lockPtrs[2];
ds_music->Lock(*writepos,size*2,lockPtrs,lockSizes,lockPtrs+1,lockSizes+1,0);
for (int j=0;j<2;j++)
{
short *target=(short *)lockPtrs[j];
for (DWORD i=0;i<lockSizes[j];i+=2)
{
int val=accnums[curchan]+xlat[*data++];
if (val>32767)
{accnums[curchan]-=val-32768;val=32767;}
if (val<-32767)
{accnums[curchan]-=val+32768;val=-32767;}
accnums[curchan]=val;
/* if (data[-1]==0) //pridano jako provizorni reseni pro korekci chyby komprimacniho programu
{
val-=31767;
}*/
*target++=val;
curchan++;
if (curchan>=2) curchan=0;
}
}
ds_music->Unlock(lockPtrs[0],lockSizes[0],lockPtrs[1],lockSizes[1]);
writepos[0]+=size*2;
if (writepos[0]>caps.dwBufferBytes) writepos[0]-=caps.dwBufferBytes;
return 1;
}
void DoneVideoSound(void *buffer)
{
IDirectSoundBuffer8 *ds_music=(IDirectSoundBuffer8 *)buffer;
ds_music->Stop();
ds_music->Release();
}
}

1247
libs/zvuka.asm Normal file

File diff suppressed because it is too large Load diff