fastarrays works properly now.

changed stereo -> numchannels in the sound code
added/tweeked the download menu
fixed a coupld of fs functions
switched the key config menu to mouse-driven
right click now closes menus


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1901 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-01-28 06:41:20 +00:00
parent f3f02e5353
commit 6f98f6f108
15 changed files with 611 additions and 245 deletions

View File

@ -14,6 +14,7 @@
#define DPF_DISPLAYVERSION 4 //some sort of conflict, the package is listed twice, so show versions so the user knows what's old. #define DPF_DISPLAYVERSION 4 //some sort of conflict, the package is listed twice, so show versions so the user knows what's old.
#define DPF_DELETEONUNINSTALL 8 //for previously installed packages, remove them from the list #define DPF_DELETEONUNINSTALL 8 //for previously installed packages, remove them from the list
#define DPF_DOWNLOADING 16 #define DPF_DOWNLOADING 16
#define DPF_ENQUED 32
int dlcount=1; int dlcount=1;
@ -25,6 +26,7 @@ char *downloadablelist[256] = {
char *downloadablelistnameprefix[256] = { char *downloadablelistnameprefix[256] = {
"" ""
}; };
char downloadablelistreceived[256]; //well
int numdownloadablelists = 1; int numdownloadablelists = 1;
typedef struct package_s { typedef struct package_s {
@ -45,10 +47,9 @@ typedef struct package_s {
typedef struct { typedef struct {
menucustom_t *list; menucustom_t *list;
char intermediatefilename[MAX_QPATH]; char intermediatefilename[MAX_QPATH];
char pathprefix[MAX_QPATH];
int parsedsourcenum; int parsedsourcenum;
qboolean populated;
int firstpackagenum;
int highlightednum;
} dlmenu_t; } dlmenu_t;
package_t *availablepackages; package_t *availablepackages;
@ -100,14 +101,12 @@ static package_t *BuildPackageList(vfsfile_t *f, int flags, char *prefix)
int i; int i;
sl = Cmd_Argv(1); sl = Cmd_Argv(1);
for (i = 0; i < sizeof(downloadablelist)/sizeof(downloadablelist[0])-1; i++) for (i = 0; i < numdownloadablelists; i++)
{ {
if (!downloadablelist[i])
break;
if (!strcmp(downloadablelist[i], sl)) if (!strcmp(downloadablelist[i], sl))
break; break;
} }
if (!downloadablelist[i]) if (i == numdownloadablelists && i != 256)
{ {
downloadablelist[i] = BZ_Malloc(strlen(sl)+1); downloadablelist[i] = BZ_Malloc(strlen(sl)+1);
strcpy(downloadablelist[i], sl); strcpy(downloadablelist[i], sl);
@ -119,6 +118,8 @@ static package_t *BuildPackageList(vfsfile_t *f, int flags, char *prefix)
downloadablelistnameprefix[i] = BZ_Malloc(strlen(sl)+1); downloadablelistnameprefix[i] = BZ_Malloc(strlen(sl)+1);
strcpy(downloadablelistnameprefix[i], sl); strcpy(downloadablelistnameprefix[i], sl);
numdownloadablelists++;
i++; i++;
} }
continue; continue;
@ -246,15 +247,289 @@ static void dlnotification(char *localfile, qboolean sucess)
int i; int i;
vfsfile_t *f; vfsfile_t *f;
COM_RefreshFSCache_f(); COM_RefreshFSCache_f();
i = atoi(localfile+7);
f = FS_OpenVFS (localfile, "rb", FS_GAME); f = FS_OpenVFS (localfile, "rb", FS_GAME);
if (f) if (f)
{ {
i = atoi(localfile+7); downloadablelistreceived[i] = 1;
ConcatPackageLists(BuildPackageList(f, 0, downloadablelistnameprefix[i])); ConcatPackageLists(BuildPackageList(f, 0, downloadablelistnameprefix[i]));
VFS_CLOSE(f); VFS_CLOSE(f);
} }
else
downloadablelistreceived[i] = -1;
} }
static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
{
package_t *p;
p = c->data;
if (p)
{
Draw_Character (x, y, 128);
Draw_Character (x+8, y, 130);
Draw_Character (x+16, y, 128);
Draw_Character (x+24, y, 130);
if (p->flags&DPF_WANTTOINSTALL)
Draw_Character (x+4, y, 131);
else
Draw_Character (x+4, y, 129);
//if you have it already
if (p->flags&(DPF_HAVEAVERSION | ((((int)(realtime*4))&1)?(DPF_DOWNLOADING|DPF_ENQUED):0) ))
Draw_Character (x+20, y, 131);
else
Draw_Character (x+20, y, 129);
if (&m->selecteditem->common == &c->common)
Draw_Alt_String (x+48, y, p->name);
else
Draw_String(x+48, y, p->name);
if (p->flags & DPF_DISPLAYVERSION)
{
Draw_String(x+48+strlen(p->name)*8, y, va(" (%i.%i)", p->version/1000, p->version%1000));
}
}
}
static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key)
{
package_t *p, *p2;
p = c->data;
if (key == K_ENTER || key == K_MOUSE1)
{
p->flags ^= DPF_WANTTOINSTALL;
if (p->flags&DPF_WANTTOINSTALL)
{
for (p2 = availablepackages; p2; p2 = p2->next)
{
if (p == p2)
continue;
if (!strcmp(p->dest, p2->dest))
p2->flags &= ~DPF_WANTTOINSTALL;
}
}
else
p->flags &= ~DPF_ENQUED;
return true;
}
return false;
}
qboolean MD_PopMenu (union menuoption_s *mo,struct menu_s *m,int key)
{
if (key == K_ENTER || key == K_MOUSE1)
{
M_RemoveMenu(m);
return true;
}
return false;
}
static void Menu_Download_Got(char *fname, qboolean successful);
qboolean MD_ApplyDownloads (union menuoption_s *mo,struct menu_s *m,int key)
{
if (key == K_ENTER || key == K_MOUSE1)
{
char *temp;
package_t *last = NULL, *p;
for (p = availablepackages; p ; p=p->next)
{
if (!(p->flags&DPF_WANTTOINSTALL) && (p->flags&DPF_HAVEAVERSION))
{ //if we don't want it but we have it anyway:
if (*p->gamedir)
{
char *fname = va("%s", p->gamedir, p->dest);
FS_Remove(fname, FS_BASE);
}
else
FS_Remove(p->dest, FS_GAME);
p->flags&=~DPF_HAVEAVERSION; //FIXME: This is error prone.
WriteInstalledPackages();
if (p->flags & DPF_DELETEONUNINSTALL)
{
if (last)
last->next = p->next;
else
availablepackages = p->next;
// BZ_Free(p);
return true;
}
}
last = p;
}
for (p = availablepackages; p ; p=p->next)
{
if ((p->flags&DPF_WANTTOINSTALL) && !(p->flags&(DPF_HAVEAVERSION|DPF_DOWNLOADING)))
{ //if we want it and don't have it:
p->dlnum = dlcount++;
temp = va("dl_%i.tmp", p->dlnum);
Con_Printf("Downloading %s (to %s)\n", p->fullname, temp);
p->flags|=DPF_DOWNLOADING;
if (!HTTP_CL_Get(p->src, temp, Menu_Download_Got))
p->flags&=~DPF_DOWNLOADING;
}
}
return true;
}
return false;
}
void M_AddItemsToDownloadMenu(menu_t *m)
{
char path[MAX_QPATH];
int y;
package_t *p;
menucustom_t *c;
int slashpos;
char *slash;
menuoption_t *mo;
dlmenu_t *info = m->data;
int prefixlen;
p = availablepackages;
MC_AddWhiteText(m, 4, 40, "W H (want, have)", false);
prefixlen = strlen(info->pathprefix);
y = 48;
for (p = availablepackages; p; p = p->next)
{
if (strncmp(p->fullname, info->pathprefix, prefixlen))
continue;
slash = strchr(p->fullname+prefixlen, '/');
if (slash)
{
Q_strncpyz(path, p->fullname, MAX_QPATH);
slash = strchr(path+prefixlen, '/');
if (slash)
*slash = '\0';
for (mo = m->options; mo; mo = mo->common.next)
if (mo->common.type == mt_button)
if (!strcmp(mo->button.text, path + prefixlen))
break;
if (!mo)
{
MC_AddConsoleCommand(m, 5*8, y, path+prefixlen, va("menu_download \"%s/\"", path));
y += 8;
}
}
else
{
c = MC_AddCustom(m, 0, y, p);
c->draw = MD_Draw;
c->key = MD_Key;
c->common.width = 320;
c->common.height = 8;
y += 8;
}
}
y+=4;
MC_AddCommand(m, 0, y, " Back", MD_PopMenu);
y+=8;
MC_AddCommand(m, 0, y, " Apply", MD_ApplyDownloads);
/*
for (pn = 1, p = availablepackages; p && pn < info->firstpackagenum ; p=p->next, pn++)
m->
if (lastpathlen != p->name - p->fullname || strncmp(p->fullname, lastpath, lastpathlen))
{
lastpathlen = p->name - p->fullname;
lastpath = p->fullname;
if (!lastpathlen)
Draw_FunStringLen(x+40, y, "/", 1);
else
Draw_FunStringLen(x+40, y, p->fullname, lastpathlen);
y+=8;
}
Draw_Character (x, y, 128);
Draw_Character (x+8, y, 130);
Draw_Character (x+16, y, 128);
Draw_Character (x+24, y, 130);
//if you want it
if (p->flags&DPF_WANTTOINSTALL)
Draw_Character (x+4, y, 131);
else
Draw_Character (x+4, y, 129);
//if you have it already
if (p->flags&(DPF_HAVEAVERSION | ((((int)(realtime*4))&1)?DPF_DOWNLOADING:0) ))
Draw_Character (x+20, y, 131);
else
Draw_Character (x+20, y, 129);
if (pn == info->highlightednum)
Draw_Alt_String(x+48, y, p->name);
else
Draw_String(x+48, y, p->name);
if (p->flags & DPF_DISPLAYVERSION)
{
Draw_String(x+48+strlen(p->name)*8, y, va(" (%i.%i)", p->version/1000, p->version%1000));
}
*/
}
void M_Download_UpdateStatus(struct menu_s *m)
{
dlmenu_t *info = m->data;
int i;
while (!cls.downloadmethod && (info->parsedsourcenum==-1 || info->parsedsourcenum < numdownloadablelists))
{ //done downloading
char basename[64];
info->parsedsourcenum++;
if (info->parsedsourcenum < numdownloadablelists)
{
if (!downloadablelistreceived[info->parsedsourcenum])
{
sprintf(basename, "dlinfo_%i.inf", info->parsedsourcenum);
if (!HTTP_CL_Get(downloadablelist[info->parsedsourcenum], basename, dlnotification))
Con_Printf("Could not contact server\n");
return;
}
}
}
for (i = 0; i < numdownloadablelists; i++)
{
if (!downloadablelistreceived[i])
{
// Draw_String(x+8, y+8, "Waiting for package list");
return;
}
}
if (!availablepackages)
{
// Draw_String(x+8, y+8, "Could not obtain a package list");
return;
}
if (!info->populated)
{
info->populated = true;
M_AddItemsToDownloadMenu(m);
}
}
/*
static void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m) static void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
{ {
int pn; int pn;
@ -265,24 +540,8 @@ static void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s
package_t *p; package_t *p;
dlmenu_t *info = m->data; dlmenu_t *info = m->data;
if (!cls.downloadmethod && (info->parsedsourcenum==-1 || downloadablelist[info->parsedsourcenum])) int i;
{ //done downloading
char basename[64];
info->parsedsourcenum++;
if (downloadablelist[info->parsedsourcenum])
{
sprintf(basename, "dlinfo_%i.inf", info->parsedsourcenum);
if (!HTTP_CL_Get(downloadablelist[info->parsedsourcenum], basename, dlnotification))
Con_Printf("Could not contact server\n");
}
}
if (!availablepackages)
{
Draw_String(x+8, y+8, "Could not obtain a package list");
return;
}
y+=8; y+=8;
Draw_Alt_String(x+4, y, "I H"); Draw_Alt_String(x+4, y, "I H");
@ -333,9 +592,10 @@ static void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s
} }
} }
} }
*/
static void Menu_Download_Got(char *fname, qboolean successful) static void Menu_Download_Got(char *fname, qboolean successful)
{ {
char *ext;
package_t *p; package_t *p;
int dlnum = atoi(fname+3); int dlnum = atoi(fname+3);
@ -344,7 +604,7 @@ static void Menu_Download_Got(char *fname, qboolean successful)
if (p->dlnum == dlnum) if (p->dlnum == dlnum)
{ {
char *destname; char *destname;
char *diskname = va("%s/%s", com_gamedir, fname); char *diskname = fname;
if (!successful) if (!successful)
{ {
@ -353,11 +613,6 @@ static void Menu_Download_Got(char *fname, qboolean successful)
return; return;
} }
if (*p->gamedir)
destname = va("%s/%s", p->gamedir, p->dest);
else
destname = va("%s", p->dest);
if (!(p->flags & DPF_DOWNLOADING)) if (!(p->flags & DPF_DOWNLOADING))
{ {
Con_Printf("menu_download: We're not downloading %s, apparently\n", p->dest); Con_Printf("menu_download: We're not downloading %s, apparently\n", p->dest);
@ -366,11 +621,21 @@ static void Menu_Download_Got(char *fname, qboolean successful)
p->flags &= ~DPF_DOWNLOADING; p->flags &= ~DPF_DOWNLOADING;
ext = COM_FileExtension(p->dest);
if (!stricmp(ext, "pak") || !stricmp(ext, "pk3"))
FS_UnloadPackFiles(); //we reload them after
if (!FS_Rename2(diskname, destname, FS_GAME, *p->gamedir?FS_BASE:FS_GAME)) if (*p->gamedir)
destname = va("%s/%s", p->gamedir, p->dest);
else
destname = va("%s", p->dest);
if (!FS_Remove(destname, *p->gamedir?FS_BASE:FS_GAME))
Con_Printf("Deleted old %s\n", destname);
if (FS_Rename2(diskname, destname, FS_GAME, *p->gamedir?FS_BASE:FS_GAME))
{ {
Con_Printf("Couldn't rename %s to %s. Removed instead.\nPerhaps you already have it\n", diskname, destname); Con_Printf("Couldn't rename %s to %s. Removed instead.\n", diskname, destname);
unlink(diskname); FS_Remove (diskname, FS_GAME);
return; return;
} }
Con_Printf("Downloaded %s (to %s)\n", p->name, destname); Con_Printf("Downloaded %s (to %s)\n", p->name, destname);
@ -378,14 +643,16 @@ static void Menu_Download_Got(char *fname, qboolean successful)
WriteInstalledPackages(); WriteInstalledPackages();
FS_ReloadPackFiles(); ext = COM_FileExtension(p->dest);
if (!stricmp(ext, "pak") || !stricmp(ext, "pk3"))
FS_ReloadPackFiles();
return; return;
} }
} }
Con_Printf("menu_download: Can't figure out where %s came from\n", fname); Con_Printf("menu_download: Can't figure out where %s came from\n", fname);
} }
/*
static qboolean M_Download_Key (struct menucustom_s *c, struct menu_s *m, int key) static qboolean M_Download_Key (struct menucustom_s *c, struct menu_s *m, int key)
{ {
char *temp; char *temp;
@ -476,9 +743,10 @@ static qboolean M_Download_Key (struct menucustom_s *c, struct menu_s *m, int ke
} }
return false; return false;
} }
*/
void Menu_DownloadStuff_f (void) void Menu_DownloadStuff_f (void)
{ {
int i;
menu_t *menu; menu_t *menu;
dlmenu_t *info; dlmenu_t *info;
@ -488,12 +756,21 @@ void Menu_DownloadStuff_f (void)
menu = M_CreateMenu(sizeof(dlmenu_t)); menu = M_CreateMenu(sizeof(dlmenu_t));
info = menu->data; info = menu->data;
menu->event = M_Download_UpdateStatus;
/*
menu->selecteditem = (menuoption_t *)(info->list = MC_AddCustom(menu, 0, 32, NULL)); menu->selecteditem = (menuoption_t *)(info->list = MC_AddCustom(menu, 0, 32, NULL));
info->list->draw = M_Download_Draw; info->list->draw = M_Download_Draw;
info->list->key = M_Download_Key; info->list->key = M_Download_Key;
*/
info->parsedsourcenum = -1; info->parsedsourcenum = -1;
Q_strncpyz(info->pathprefix, Cmd_Argv(1), sizeof(info->pathprefix));
if (!*info->pathprefix)
{
for (i = 0; i < numdownloadablelists; i++)
downloadablelistreceived[i] = 0;
}
MC_AddWhiteText(menu, 24, 8, "Downloads", false); MC_AddWhiteText(menu, 24, 8, "Downloads", false);
MC_AddWhiteText(menu, 0, 16, "Probably buggy, press escape now and avoid this place!", false); MC_AddWhiteText(menu, 0, 16, "Probably buggy, press escape now and avoid this place!", false);
MC_AddWhiteText(menu, 16, 24, "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37", false); MC_AddWhiteText(menu, 16, 24, "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37", false);

View File

@ -400,6 +400,8 @@ menubind_t *MC_AddBind(menu_t *menu, int x, int y, const char *caption, char *co
strcpy(n->caption, caption); strcpy(n->caption, caption);
n->command = n->caption+strlen(n->caption)+1; n->command = n->caption+strlen(n->caption)+1;
strcpy(n->command, command); strcpy(n->command, command);
n->common.width = strlen(caption)*8 + 64;
n->common.height = 8;
n->common.next = menu->options; n->common.next = menu->options;
menu->options = (menuoption_t *)n; menu->options = (menuoption_t *)n;
@ -534,14 +536,14 @@ menubox_t *MC_AddBox(menu_t *menu, int x, int y, int width, int height)
return n; return n;
} }
menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, const char *data) menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, void *data)
{ {
menucustom_t *n = Z_Malloc(sizeof(menucustom_t)); menucustom_t *n = Z_Malloc(sizeof(menucustom_t));
n->common.type = mt_custom; n->common.type = mt_custom;
n->common.iszone = true; n->common.iszone = true;
n->common.posx = x; n->common.posx = x;
n->common.posy = y; n->common.posy = y;
n->data = NULL; n->data = data;
n->common.next = menu->options; n->common.next = menu->options;
menu->options = (menuoption_t *)n; menu->options = (menuoption_t *)n;
@ -700,6 +702,8 @@ menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*c
n->text = text; n->text = text;
n->command = NULL; n->command = NULL;
n->key = command; n->key = command;
n->common.height = 8;
n->common.width = strlen(text)*8;
n->common.next = menu->options; n->common.next = menu->options;
menu->options = (menuoption_t *)n; menu->options = (menuoption_t *)n;
@ -1043,12 +1047,12 @@ menuoption_t *M_NextSelectableItem(menu_t *m, menuoption_t *old)
if (op == old) if (op == old)
{ {
if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_buttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind) if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_buttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind || op->common.type == mt_custom)
return op; return op;
return NULL; //whoops. return NULL; //whoops.
} }
if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_buttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind) if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_buttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind || op->common.type == mt_custom)
if (!op->common.ishidden) if (!op->common.ishidden)
return op; return op;
} }
@ -1075,7 +1079,7 @@ menuoption_t *M_PrevSelectableItem(menu_t *m, menuoption_t *old)
if (op == old) if (op == old)
return old; //whoops. return old; //whoops.
if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_buttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind) if (op->common.type == mt_slider || op->common.type == mt_checkbox || op->common.type == mt_button || op->common.type == mt_buttonbigfont || op->common.type == mt_edit || op->common.type == mt_combo || op->common.type == mt_bind || op->common.type == mt_custom)
if (!op->common.ishidden) if (!op->common.ishidden)
return op; return op;
} }
@ -1111,6 +1115,7 @@ void M_Complex_Key(int key)
switch(key) switch(key)
{ {
case K_MOUSE2:
case K_ESCAPE: case K_ESCAPE:
//remove //remove
M_RemoveMenu(currentmenu); M_RemoveMenu(currentmenu);
@ -1172,7 +1177,7 @@ void M_Complex_Key(int key)
MC_Combo_Key(&currentmenu->selecteditem->combo, key); MC_Combo_Key(&currentmenu->selecteditem->combo, key);
break; break;
case mt_bind: case mt_bind:
if (key == K_ENTER) if (key == K_ENTER || key == K_MOUSE1)
bindingactive = true; bindingactive = true;
else if (key == K_BACKSPACE || key == K_DEL) else if (key == K_BACKSPACE || key == K_DEL)
M_UnbindCommand (currentmenu->selecteditem->bind.command); M_UnbindCommand (currentmenu->selecteditem->bind.command);

View File

@ -87,6 +87,7 @@ void M_Menu_Options_f (void)
MC_AddConsoleCommand(menu, 16, y, " Video Options", "menu_video\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " Video Options", "menu_video\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " FPS Options", "menu_fps\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " FPS Options", "menu_fps\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Audio Options", "menu_audio\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " Audio Options", "menu_audio\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Downloads", "menu_download\n"); y+=8;
#ifdef _WIN32 #ifdef _WIN32
if (!vid_isfullscreen) if (!vid_isfullscreen)

View File

@ -280,56 +280,56 @@ typedef struct {
bindnames_t qwbindnames[] = bindnames_t qwbindnames[] =
{ {
{"+attack", "attack"}, {"+attack", "attack "},
{"impulse 10", "change weapon"}, {"impulse 10", "change weapon "},
{"impulse 12", "prev weapon"}, {"impulse 12", "prev weapon "},
{"+jump", "jump / swim up"}, {"+jump", "jump / swim up"},
{"+forward", "walk forward"}, {"+forward", "walk forward "},
{"+back", "backpedal"}, {"+back", "backpedal "},
{"+left", "turn left"}, {"+left", "turn left "},
{"+right", "turn right"}, {"+right", "turn right "},
{"+speed", "run"}, {"+speed", "run "},
{"+moveleft", "step left"}, {"+moveleft", "step left "},
{"+moveright", "step right"}, {"+moveright", "step right "},
{"+strafe", "sidestep"}, {"+strafe", "sidestep "},
{"+lookup", "look up"}, {"+lookup", "look up "},
{"+lookdown", "look down"}, {"+lookdown", "look down "},
{"centerview", "center view"}, {"centerview", "center view "},
{"+mlook", "mouse look"}, {"+mlook", "mouse look "},
{"+klook", "keyboard look"}, {"+klook", "keyboard look "},
{"+moveup", "swim up"}, {"+moveup", "swim up "},
{"+movedown", "swim down"}, {"+movedown", "swim down "},
{NULL} {NULL}
}; };
#ifdef Q2CLIENT #ifdef Q2CLIENT
bindnames_t q2bindnames[] = bindnames_t q2bindnames[] =
{ {
{"+attack", "attack"}, {"+attack", "attack "},
{"cmd weapnext", "next weapon"}, {"cmd weapnext", "next weapon "},
{"+forward", "walk forward"}, {"+forward", "walk forward "},
{"+back", "backpedal"}, {"+back", "backpedal "},
{"+left", "turn left"}, {"+left", "turn left "},
{"+right", "turn right"}, {"+right", "turn right "},
{"+speed", "run"}, {"+speed", "run "},
{"+moveleft", "step left"}, {"+moveleft", "step left "},
{"+moveright", "step right"}, {"+moveright", "step right "},
{"+strafe", "sidestep"}, {"+strafe", "sidestep "},
{"+lookup", "look up"}, {"+lookup", "look up "},
{"+lookdown", "look down"}, {"+lookdown", "look down "},
{"centerview", "center view"}, {"centerview", "center view "},
{"+mlook", "mouse look"}, {"+mlook", "mouse look "},
{"+klook", "keyboard look"}, {"+klook", "keyboard look "},
{"+moveup", "up / jump"}, {"+moveup", "up / jump "},
{"+movedown", "down / crouch"}, {"+movedown", "down / crouch "},
{"cmd inven", "inventory"}, {"cmd inven", "inventory "},
{"cmd invuse", "use item"}, {"cmd invuse", "use item "},
{"cmd invdrop", "drop item"}, {"cmd invdrop", "drop item "},
{"cmd invprev", "prev item"}, {"cmd invprev", "prev item "},
{"cmd invnext", "next item"}, {"cmd invnext", "next item "},
{"cmd help", "help computer" }, {"cmd help", "help computer "},
{NULL} {NULL}
}; };
#endif #endif
@ -341,6 +341,36 @@ int keys_cursor;
int bind_grab; int bind_grab;
void M_Menu_Keys_f (void) void M_Menu_Keys_f (void)
{
extern cvar_t temp1;
int y;
menu_t *menu;
if (temp1.value)
{
key_dest = key_menu;
m_state = m_complex;
menu = M_CreateMenu(0);
MC_AddCenterPicture(menu, 4, "gfx/ttl_cstm.lmp");
#ifdef Q2CLIENT
if (cls.protocol == CP_QUAKE2)
bindnames = q2bindnames;
else
#endif
bindnames = qwbindnames;
y = 48;
while (bindnames->name)
{
MC_AddBind(menu, 16, y, bindnames->name, bindnames->command);
y += 8;
bindnames++;
}
}
else
{ {
key_dest = key_menu; key_dest = key_menu;
m_state = m_keys; m_state = m_keys;
@ -361,6 +391,7 @@ void M_Menu_Keys_f (void)
if (keys_cursor >= numbindnames) if (keys_cursor >= numbindnames)
keys_cursor = 0; keys_cursor = 0;
} }
}
void M_FindKeysForCommand (char *command, int *twokeys) void M_FindKeysForCommand (char *command, int *twokeys)

View File

@ -264,7 +264,7 @@ menucombo_t *MC_AddCombo(menu_t *menu, int x, int y, const char *caption, const
menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int)); menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int));
menuedit_t *MC_AddEdit(menu_t *menu, int x, int y, char *text, char *def); menuedit_t *MC_AddEdit(menu_t *menu, int x, int y, char *text, char *def);
menuedit_t *MC_AddEditCvar(menu_t *menu, int x, int y, char *text, char *name); menuedit_t *MC_AddEditCvar(menu_t *menu, int x, int y, char *text, char *name);
menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, const char *data); menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, void *data);
menu_t *M_CreateMenu (int extrasize); menu_t *M_CreateMenu (int extrasize);
void M_AddMenu (menu_t *menu); void M_AddMenu (menu_t *menu);

View File

@ -1480,7 +1480,7 @@ void S_SoundList(void)
sc = Cache_Check (&sfx->cache); sc = Cache_Check (&sfx->cache);
if (!sc) if (!sc)
continue; continue;
size = sc->length*sc->width*(sc->stereo+1); size = sc->length*sc->width*(sc->numchannels);
total += size; total += size;
if (sc->loopstart >= 0) if (sc->loopstart >= 0)
Con_Printf ("L"); Con_Printf ("L");
@ -1620,16 +1620,16 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
free->sfxcache = BZ_Malloc(sizeof(sfxcache_t)); free->sfxcache = BZ_Malloc(sizeof(sfxcache_t));
free->sfx.cache.data = free->sfxcache; free->sfx.cache.data = free->sfxcache;
free->sfxcache->speed = snd_speed; free->sfxcache->speed = snd_speed;
free->sfxcache->stereo = channels-1; free->sfxcache->numchannels = channels;
free->sfxcache->width = width; free->sfxcache->width = width;
free->sfxcache->loopstart = -1; free->sfxcache->loopstart = -1;
free->sfxcache->length = 0; free->sfxcache->length = 0;
// Con_Printf("Added new raw stream\n"); // Con_Printf("Added new raw stream\n");
} }
if (s->sfxcache->width != width || s->sfxcache->stereo != channels-1 || s->sfxcache->speed != snd_speed) if (s->sfxcache->width != width || s->sfxcache->numchannels != channels || s->sfxcache->speed != snd_speed)
{ {
s->sfxcache->width = width; s->sfxcache->width = width;
s->sfxcache->stereo = channels-1; s->sfxcache->numchannels = channels;
s->sfxcache->speed = snd_speed; s->sfxcache->speed = snd_speed;
s->sfxcache->length = 0; s->sfxcache->length = 0;
// Con_Printf("Restarting raw stream\n"); // Con_Printf("Restarting raw stream\n");
@ -1692,9 +1692,9 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
return; //let the slower sound cards catch up. (This shouldn't really happen, but it's possible two cards have slightly different timings but report the same speed) return; //let the slower sound cards catch up. (This shouldn't really happen, but it's possible two cards have slightly different timings but report the same speed)
}*/ }*/
newcache = BZ_Malloc(sizeof(sfxcache_t) + (spare+outsamples) * (s->sfxcache->stereo+1) * s->sfxcache->width); newcache = BZ_Malloc(sizeof(sfxcache_t) + (spare+outsamples) * (s->sfxcache->numchannels) * s->sfxcache->width);
memcpy(newcache, s->sfxcache, sizeof(sfxcache_t)); memcpy(newcache, s->sfxcache, sizeof(sfxcache_t));
memcpy(newcache->data, s->sfxcache->data + prepadl * (s->sfxcache->stereo+1) * s->sfxcache->width, spare * (s->sfxcache->stereo+1) * s->sfxcache->width); memcpy(newcache->data, s->sfxcache->data + prepadl * (s->sfxcache->numchannels) * s->sfxcache->width, spare * (s->sfxcache->numchannels) * s->sfxcache->width);
BZ_Free(s->sfxcache); BZ_Free(s->sfxcache);
s->sfxcache = s->sfx.cache.data = newcache; s->sfxcache = s->sfx.cache.data = newcache;
@ -1708,7 +1708,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
{ {
short sample; short sample;
short *indata = (short *)data; short *indata = (short *)data;
short *outpos = (short *)(newcache->data + spare * (s->sfxcache->stereo+1) * s->sfxcache->width); short *outpos = (short *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width);
if (speedfactor==1) //fast if (speedfactor==1) //fast
{ {
while (samples--) while (samples--)
@ -1734,7 +1734,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
{ {
char sample; char sample;
char *indata = (char *)data; char *indata = (char *)data;
char *outpos = (char *)(newcache->data + spare * (s->sfxcache->stereo+1) * s->sfxcache->width); char *outpos = (char *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width);
if (speedfactor==1) //fast if (speedfactor==1) //fast
{ {
while (samples--) while (samples--)
@ -1765,7 +1765,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
{ {
short sample; short sample;
short *indata = (short *)data; short *indata = (short *)data;
short *outpos = (short *)((qbyte *)newcache->data + spare * (s->sfxcache->stereo+1) * s->sfxcache->width); short *outpos = (short *)((qbyte *)newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width);
if (speedfactor==1) //fast if (speedfactor==1) //fast
{ {
while (samples--) while (samples--)

View File

@ -59,7 +59,7 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data)
else else
sc->width = inwidth; sc->width = inwidth;
if (sc->stereo) if (sc->numchannels==2)
{ {
if (stepscale == 1 && inwidth == 1 && sc->width == 1) if (stepscale == 1 && inwidth == 1 && sc->width == 1)
{ {
@ -176,7 +176,7 @@ sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
sc->loopstart = info.loopstart; sc->loopstart = info.loopstart;
sc->speed = info.rate; sc->speed = info.rate;
sc->width = info.width; sc->width = info.width;
sc->stereo = info.numchannels-1; sc->numchannels = info.numchannels;
ResampleSfx (s, sc->speed, sc->width, data + info.dataofs); ResampleSfx (s, sc->speed, sc->width, data + info.dataofs);

View File

@ -492,7 +492,7 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
*/ */
if (scache->width == 1) if (scache->width == 1)
{ {
if (scache->stereo) if (scache->numchannels==2)
SND_PaintChannelFrom8Stereo(ch, scache, count); SND_PaintChannelFrom8Stereo(ch, scache, count);
else if (sc->sn.numchannels == 6) else if (sc->sn.numchannels == 6)
SND_PaintChannelFrom8_6Speaker(ch, scache, count); SND_PaintChannelFrom8_6Speaker(ch, scache, count);
@ -503,7 +503,7 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
} }
else else
{ {
if (scache->stereo) if (scache->numchannels==2)
SND_PaintChannelFrom16Stereo(ch, scache, count); SND_PaintChannelFrom16Stereo(ch, scache, count);
else if (sc->sn.numchannels == 6) else if (sc->sn.numchannels == 6)
SND_PaintChannelFrom16_6Speaker(ch, scache, count); SND_PaintChannelFrom16_6Speaker(ch, scache, count);

View File

@ -114,7 +114,7 @@ int OV_DecodeSome(sfx_t *s, int minlength)
s->cache.fake = true; s->cache.fake = true;
sc = s->cache.data; sc = s->cache.data;
sc->stereo = dec->mediasc.stereo; sc->numchannels = dec->mediasc.numchannels;
sc->loopstart = -1; sc->loopstart = -1;
} }
else else
@ -138,7 +138,7 @@ int OV_DecodeSome(sfx_t *s, int minlength)
if (snd_speed != dec->srcspeed) if (snd_speed != dec->srcspeed)
{ //resample { //resample
if (dec->mediasc.stereo) if (dec->mediasc.numchannels==2)
{ {
int *data = (int*)(dec->mediaaswavdata+dec->mediaaswavpos); int *data = (int*)(dec->mediaaswavdata+dec->mediaaswavpos);
float frac = (float)dec->srcspeed/snd_speed; float frac = (float)dec->srcspeed/snd_speed;
@ -152,7 +152,7 @@ int OV_DecodeSome(sfx_t *s, int minlength)
} }
dec->mediaaswavpos += bytesread; dec->mediaaswavpos += bytesread;
sc->length = (dec->mediaaswavpos-sizeof(sfxcache_t))/(2*(dec->mediasc.stereo+1)); sc->length = (dec->mediaaswavpos-sizeof(sfxcache_t))/(2*(dec->mediasc.numchannels));
dec->mediasc.length = sc->length; dec->mediasc.length = sc->length;
if (minlength<=sc->length) if (minlength<=sc->length)
@ -293,7 +293,7 @@ qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuf
return false; return false;
} }
buffer->mediasc.stereo = vi->channels-1; buffer->mediasc.numchannels = vi->channels;
buffer->mediasc.loopstart = -1; buffer->mediasc.loopstart = -1;
buffer->srcspeed = vi->rate; buffer->srcspeed = vi->rate;
/* /*

View File

@ -59,7 +59,7 @@ typedef struct sfxcache_s
int loopstart; int loopstart;
int speed; int speed;
int width; int width;
int stereo; int numchannels;
qbyte data[1]; // variable sized qbyte data[1]; // variable sized
} sfxcache_t; } sfxcache_t;

View File

@ -2361,6 +2361,10 @@ void Cmd_set_f(void)
{ {
text = If_Token(text, &end); text = If_Token(text, &end);
Cvar_Set(var, text); Cvar_Set(var, text);
var->flags |= CVAR_USERCREATED;
if (!stricmp(Cmd_Argv(0), "seta"))
var->flags |= CVAR_ARCHIVE;
} }
} }
else else
@ -2375,7 +2379,7 @@ void Cmd_set_f(void)
var = Cvar_Get(Cmd_Argv(1), text, 0, "User variables"); var = Cvar_Get(Cmd_Argv(1), text, 0, "User variables");
} }
if (!Cmd_FromGamecode()) if (var && !Cmd_FromGamecode())
if (!stricmp(Cmd_Argv(0), "seta")) if (!stricmp(Cmd_Argv(0), "seta"))
var->flags |= CVAR_ARCHIVE|CVAR_USERCREATED; var->flags |= CVAR_ARCHIVE|CVAR_USERCREATED;

View File

@ -49,6 +49,8 @@ char *VFS_GETS(vfsfile_t *vf, char *buffer, int buflen)
{ {
if (!VFS_READ(vf, &in, 1)) if (!VFS_READ(vf, &in, 1))
{ {
if (len == buflen-1)
return NULL;
*out = '\0'; *out = '\0';
return buffer; return buffer;
} }
@ -1052,7 +1054,7 @@ searchpath_t *com_base_searchpaths; // without gamedirs
static void COM_AddDataFiles(char *pathto, searchpath_t *search, char *extension, searchpathfuncs_t *funcs); static void COM_AddDataFiles(char *pathto, searchpath_t *search, char *extension, searchpathfuncs_t *funcs);
searchpath_t *COM_AddPathHandle(char *probablepath, searchpathfuncs_t *funcs, void *handle, qboolean copyprotect, qboolean istemporary) searchpath_t *COM_AddPathHandle(char *probablepath, searchpathfuncs_t *funcs, void *handle, qboolean copyprotect, qboolean istemporary, unsigned int loadstuff)
{ {
searchpath_t *search; searchpath_t *search;
@ -1069,13 +1071,13 @@ searchpath_t *COM_AddPathHandle(char *probablepath, searchpathfuncs_t *funcs, vo
//add any data files too //add any data files too
// if (loadstuff & 2) if (loadstuff & 2)
COM_AddDataFiles(probablepath, search, "pak", &packfilefuncs);//q1/hl/h2/q2 COM_AddDataFiles(probablepath, search, "pak", &packfilefuncs);//q1/hl/h2/q2
//pk2s never existed. //pk2s never existed.
#ifdef AVAIL_ZLIB #ifdef AVAIL_ZLIB
// if (loadstuff & 4) if (loadstuff & 4)
COM_AddDataFiles(probablepath, search, "pk3", &zipfilefuncs); //q3 + offspring COM_AddDataFiles(probablepath, search, "pk3", &zipfilefuncs); //q3 + offspring
// if (loadstuff & 8) if (loadstuff & 8)
COM_AddDataFiles(probablepath, search, "pk4", &zipfilefuncs); //q4 COM_AddDataFiles(probablepath, search, "pk4", &zipfilefuncs); //q4
//we could easily add zip, but it's friendlier not to //we could easily add zip, but it's friendlier not to
#endif #endif
@ -1663,7 +1665,7 @@ vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto)
return NULL; return NULL;
} }
void FS_Rename2(char *oldf, char *newf, int oldrelativeto, int newrelativeto) int FS_Rename2(char *oldf, char *newf, int oldrelativeto, int newrelativeto)
{ {
char oldfullname[MAX_OSPATH]; char oldfullname[MAX_OSPATH];
char newfullname[MAX_OSPATH]; char newfullname[MAX_OSPATH];
@ -1716,7 +1718,11 @@ void FS_Rename2(char *oldf, char *newf, int oldrelativeto, int newrelativeto)
Sys_Error("FS_Rename case not handled\n"); Sys_Error("FS_Rename case not handled\n");
} }
rename(va("%s%s", oldfullname, oldf), va("%s%s", newfullname, newf)); Q_strncatz(oldfullname, oldf, sizeof(oldfullname));
Q_strncatz(newfullname, newf, sizeof(newfullname));
FS_CreatePath(newf, newrelativeto);
return rename(oldfullname, newfullname);
} }
int FS_Rename(char *oldf, char *newf, int relativeto) int FS_Rename(char *oldf, char *newf, int relativeto)
{ {
@ -1749,7 +1755,33 @@ int FS_Rename(char *oldf, char *newf, int relativeto)
} }
int FS_Remove(char *fname, int relativeto) int FS_Remove(char *fname, int relativeto)
{ {
return unlink (fname); char fullname[MAX_OSPATH];
switch (relativeto)
{
case FS_GAME:
if (*com_homedir)
_snprintf(fullname, sizeof(fullname), "%s/%s/%s", com_homedir, gamedirfile, fname);
else
_snprintf(fullname, sizeof(fullname), "%s/%s/%s", com_quakedir, gamedirfile, fname);
break;
case FS_SKINS:
if (*com_homedir)
_snprintf(fullname, sizeof(fullname), "%s/qw/skins/%s", com_homedir, fname);
else
_snprintf(fullname, sizeof(fullname), "%s/qw/skins/%s", com_quakedir, fname);
break;
case FS_BASE:
if (*com_homedir)
_snprintf(fullname, sizeof(fullname), "%s/%s", com_homedir, fname);
else
_snprintf(fullname, sizeof(fullname), "%s/%s", com_quakedir, fname);
break;
default:
Sys_Error("FS_Rename case not handled\n");
}
return unlink (fullname);
} }
void FS_CreatePath(char *pname, int relativeto) void FS_CreatePath(char *pname, int relativeto)
{ {
@ -1761,10 +1793,22 @@ void FS_CreatePath(char *pname, int relativeto)
_snprintf(fullname, sizeof(fullname), "%s/%s", com_gamedir, pname); _snprintf(fullname, sizeof(fullname), "%s/%s", com_gamedir, pname);
break; break;
case FS_BASE: case FS_BASE:
_snprintf(fullname, sizeof(fullname), "%s/%s", com_homedir, pname); if (*com_homedir)
_snprintf(fullname, sizeof(fullname), "%s/%s", com_homedir, pname);
else
_snprintf(fullname, sizeof(fullname), "%s/%s", com_quakedir, pname);
break;
case FS_SKINS:
if (*com_homedir)
_snprintf(fullname, sizeof(fullname), "%s/qw/skins/%s", com_homedir, pname);
else
_snprintf(fullname, sizeof(fullname), "%s/qw/skins/%s", com_quakedir, pname);
break; break;
case FS_CONFIGONLY: case FS_CONFIGONLY:
_snprintf(fullname, sizeof(fullname), "%s/fte/%s", com_homedir, pname); if (*com_homedir)
_snprintf(fullname, sizeof(fullname), "%s/fte/%s", com_homedir, pname);
else
_snprintf(fullname, sizeof(fullname), "%s/fte/%s", com_quakedir, pname);
break; break;
default: default:
Sys_Error("FS_CreatePath: Bad relative path"); Sys_Error("FS_CreatePath: Bad relative path");
@ -2272,7 +2316,7 @@ static int COM_AddWildDataFiles (char *descriptor, int size, void *vparam)
return true; return true;
sprintf (pakfile, "%s%s/", param->parentdesc, descriptor); sprintf (pakfile, "%s%s/", param->parentdesc, descriptor);
COM_AddPathHandle(pakfile, funcs, pak, true, false); COM_AddPathHandle(pakfile, funcs, pak, true, false, (unsigned int)-1);
return true; return true;
} }
@ -2302,7 +2346,7 @@ static void COM_AddDataFiles(char *pathto, searchpath_t *search, char *extension
if (!handle) if (!handle)
break; break;
_snprintf (pakfile, sizeof(pakfile), "%spak%i.%s/", pathto, i, extension); _snprintf (pakfile, sizeof(pakfile), "%spak%i.%s/", pathto, i, extension);
COM_AddPathHandle(pakfile, funcs, handle, true, false); COM_AddPathHandle(pakfile, funcs, handle, true, false, (unsigned int)-1);
} }
sprintf (pakfile, "*.%s", extension); sprintf (pakfile, "*.%s", extension);
@ -2356,7 +2400,7 @@ void COM_AddGameDirectory (char *dir, unsigned int loadstuff)
p = Z_Malloc(strlen(dir)+1); p = Z_Malloc(strlen(dir)+1);
strcpy(p, dir); strcpy(p, dir);
COM_AddPathHandle(va("%s/", dir), &osfilefuncs, p, false, false); COM_AddPathHandle(va("%s/", dir), &osfilefuncs, p, false, false, loadstuff);
} }
char *COM_NextPath (char *prevpath) char *COM_NextPath (char *prevpath)
@ -2723,6 +2767,11 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
com_base_searchpaths = com_searchpaths; com_base_searchpaths = com_searchpaths;
} }
void FS_UnloadPackFiles(void)
{
FS_ReloadPackFilesFlags(1);
}
void FS_ReloadPackFiles(void) void FS_ReloadPackFiles(void)
{ {
FS_ReloadPackFilesFlags((unsigned int)-1); FS_ReloadPackFilesFlags((unsigned int)-1);

View File

@ -741,7 +741,7 @@ if (pr_typecurrent != 0)
case OP_FETCH_GBL_E: case OP_FETCH_GBL_E:
case OP_FETCH_GBL_FNC: case OP_FETCH_GBL_FNC:
i = (int)OPB->_float; i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1)) if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{ {
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i); PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
} }
@ -750,7 +750,7 @@ if (pr_typecurrent != 0)
break; break;
case OP_FETCH_GBL_V: case OP_FETCH_GBL_V:
i = (int)OPB->_float; i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1)) if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{ {
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i); PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
} }

View File

@ -1789,14 +1789,12 @@ QCC_PR_SimpleStatement
Emits a primitive statement, returning the var it places it's value in Emits a primitive statement, returning the var it places it's value in
============ ============
*/ */
QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c) QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c, int force)
{ {
QCC_dstatement_t *statement; QCC_dstatement_t *statement;
if (!QCC_OPCodeValid(pr_opcodes+op)) if (!force && !QCC_OPCodeValid(pr_opcodes+op))
{ {
// outputversion = op->extension;
// if (noextensions)
QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target\n", pr_opcodes[op].name, pr_opcodes[op].opname); QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target\n", pr_opcodes[op].name, pr_opcodes[op].opname);
} }
@ -1811,11 +1809,11 @@ QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_
return statement; return statement;
} }
void QCC_PR_Statement3 ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_def_t *var_c) void QCC_PR_Statement3 ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_def_t *var_c, int force)
{ {
QCC_dstatement_t *statement; QCC_dstatement_t *statement;
if (!QCC_OPCodeValid(op)) if (!force && !QCC_OPCodeValid(op))
{ {
// outputversion = op->extension; // outputversion = op->extension;
// if (noextensions) // if (noextensions)
@ -2181,12 +2179,12 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
if (e) if (e)
{ {
if (d) if (d)
QCC_PR_SimpleStatement(OP_RAND2, e->ofs, d->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_RAND2, e->ofs, d->ofs, OFS_RETURN, false);
else else
QCC_PR_SimpleStatement(OP_RAND1, e->ofs, 0, OFS_RETURN); QCC_PR_SimpleStatement(OP_RAND1, e->ofs, 0, OFS_RETURN, false);
} }
else else
QCC_PR_SimpleStatement(OP_RAND0, 0, 0, OFS_RETURN); QCC_PR_SimpleStatement(OP_RAND0, 0, 0, OFS_RETURN, false);
} }
else else
{ {
@ -2196,7 +2194,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
{ {
QCC_dstatement_t *st; QCC_dstatement_t *st;
QCC_def_t *t; QCC_def_t *t;
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs)) if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs))
{ {
@ -2205,27 +2203,27 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
st->b = 3; st->b = 3;
t = QCC_PR_Statement(&pr_opcodes[OP_SUB_F], d, e, NULL); t = QCC_PR_Statement(&pr_opcodes[OP_SUB_F], d, e, NULL);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false);
QCC_FreeTemp(t); QCC_FreeTemp(t);
QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs, OFS_RETURN, false);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_GOTO], 0, 0, &st)); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_GOTO], 0, 0, &st));
st->a = 3; st->a = 3;
} }
t = QCC_PR_Statement(&pr_opcodes[OP_SUB_F], e, d, NULL); t = QCC_PR_Statement(&pr_opcodes[OP_SUB_F], e, d, NULL);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false);
QCC_FreeTemp(t); QCC_FreeTemp(t);
QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs, OFS_RETURN, false);
} }
else else
{ {
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN, false);
} }
} }
else else
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
} }
if (e) if (e)
@ -2302,12 +2300,12 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
if (e) if (e)
{ {
if (d) if (d)
QCC_PR_SimpleStatement(OP_RANDV2, e->ofs, d->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_RANDV2, e->ofs, d->ofs, OFS_RETURN, false);
else else
QCC_PR_SimpleStatement(OP_RANDV1, e->ofs, 0, OFS_RETURN); QCC_PR_SimpleStatement(OP_RANDV1, e->ofs, 0, OFS_RETURN, false);
} }
else else
QCC_PR_SimpleStatement(OP_RANDV0, 0, 0, OFS_RETURN); QCC_PR_SimpleStatement(OP_RANDV0, 0, 0, OFS_RETURN, false);
} }
else else
{ {
@ -2316,92 +2314,92 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
if (d) if (d)
{ {
QCC_def_t *t; QCC_def_t *t;
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs)) if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs))
{ {
t = QCC_GetTemp(type_float); t = QCC_GetTemp(type_float);
QCC_PR_SimpleStatement(OP_GT, d->ofs+2, e->ofs+2, t->ofs); QCC_PR_SimpleStatement(OP_GT, d->ofs+2, e->ofs+2, t->ofs, false);
QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0); QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0, false);
QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+2, e->ofs+2, t->ofs); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+2, e->ofs+2, t->ofs, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+2); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+2, false);
QCC_FreeTemp(t); QCC_FreeTemp(t);
QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs+2, OFS_RETURN+2); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs+2, OFS_RETURN+2, false);
QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0); QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false);
} }
t = QCC_GetTemp(type_float); t = QCC_GetTemp(type_float);
QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+2, e->ofs+2, t->ofs); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+2, e->ofs+2, t->ofs, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+2); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+2, false);
QCC_FreeTemp(t); QCC_FreeTemp(t);
QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs+2, OFS_RETURN+2); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs+2, OFS_RETURN+2, false);
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs)) if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs))
{ {
t = QCC_GetTemp(type_float); t = QCC_GetTemp(type_float);
QCC_PR_SimpleStatement(OP_GT, d->ofs+1, e->ofs+1, t->ofs); QCC_PR_SimpleStatement(OP_GT, d->ofs+1, e->ofs+1, t->ofs, false);
QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0); QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0, false);
QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+1, e->ofs+1, t->ofs); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+1, e->ofs+1, t->ofs, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+1); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+1, false);
QCC_FreeTemp(t); QCC_FreeTemp(t);
QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs+1, OFS_RETURN+1); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs+1, OFS_RETURN+1, false);
QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0); QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false);
} }
t = QCC_GetTemp(type_float); t = QCC_GetTemp(type_float);
QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+1, e->ofs+1, t->ofs); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+1, e->ofs+1, t->ofs, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+1); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+1, false);
QCC_FreeTemp(t); QCC_FreeTemp(t);
QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs+1, OFS_RETURN+1); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs+1, OFS_RETURN+1, false);
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs)) if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs))
{ {
t = QCC_GetTemp(type_float); t = QCC_GetTemp(type_float);
QCC_PR_SimpleStatement(OP_GT, d->ofs, e->ofs, t->ofs); QCC_PR_SimpleStatement(OP_GT, d->ofs, e->ofs, t->ofs, false);
QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0); QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0, false);
QCC_PR_SimpleStatement(OP_SUB_F, d->ofs, e->ofs, t->ofs); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs, e->ofs, t->ofs, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false);
QCC_FreeTemp(t); QCC_FreeTemp(t);
QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs, OFS_RETURN, false);
QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0); QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false);
} }
t = QCC_GetTemp(type_float); t = QCC_GetTemp(type_float);
QCC_PR_SimpleStatement(OP_SUB_F, d->ofs, e->ofs, t->ofs); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs, e->ofs, t->ofs, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false);
QCC_FreeTemp(t); QCC_FreeTemp(t);
QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs, OFS_RETURN, false);
} }
else else
{ {
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN+2); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN+2, false);
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN+1); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN+1, false);
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN, false);
} }
} }
else else
{ {
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
QCC_PR_SimpleStatement(OP_STORE_F, OFS_RETURN, OFS_RETURN+2, 0); QCC_PR_SimpleStatement(OP_STORE_F, OFS_RETURN, OFS_RETURN+2, 0, false);
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
QCC_PR_SimpleStatement(OP_STORE_F, OFS_RETURN, OFS_RETURN+1, 0); QCC_PR_SimpleStatement(OP_STORE_F, OFS_RETURN, OFS_RETURN+1, 0, false);
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
} }
} }
@ -2467,7 +2465,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
func = QCC_PR_GetDef(type_function, genfunc, NULL, true, 1); func = QCC_PR_GetDef(type_function, genfunc, NULL, true, 1);
func->references++; func->references++;
} }
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
def_ret.type = rettype; def_ret.type = rettype;
return &def_ret; return &def_ret;
} }
@ -2771,8 +2769,8 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
if (statements[laststatement-1].a != d->ofs) if (statements[laststatement-1].a != d->ofs)
{ {
oself = QCC_GetTemp(type_entity); oself = QCC_GetTemp(type_entity);
QCC_PR_SimpleStatement(OP_STORE_ENT, d->ofs, oself->ofs, 0); QCC_PR_SimpleStatement(OP_STORE_ENT, d->ofs, oself->ofs, 0, false);
QCC_PR_SimpleStatement(OP_STORE_ENT, statements[laststatement-1].a, d->ofs, 0); QCC_PR_SimpleStatement(OP_STORE_ENT, statements[laststatement-1].a, d->ofs, 0, false);
if (callconvention == OP_CALL1H) //other.function(self) if (callconvention == OP_CALL1H) //other.function(self)
//hexenc calling convention would mean that the //hexenc calling convention would mean that the
@ -2829,7 +2827,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
} }
} }
if (oself) if (oself)
QCC_PR_SimpleStatement(OP_STORE_ENT, oself->ofs, d->ofs, 0); QCC_PR_SimpleStatement(OP_STORE_ENT, oself->ofs, d->ofs, 0, false);
for(; arg; arg--) for(; arg; arg--)
{ {
@ -3200,7 +3198,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
virt = QCC_PR_GetDef(type_function, "spawn", NULL, false, 0); virt = QCC_PR_GetDef(type_function, "spawn", NULL, false, 0);
if (!virt) if (!virt)
QCC_Error(ERR_INTERNAL, "spawn function was not defined\n"); QCC_Error(ERR_INTERNAL, "spawn function was not defined\n");
QCC_PR_SimpleStatement(OP_CALL0, virt->ofs, 0, 0); //calling convention doesn't come into it. QCC_PR_SimpleStatement(OP_CALL0, virt->ofs, 0, 0, false); //calling convention doesn't come into it.
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], &def_ret, ed, NULL)); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], &def_ret, ed, NULL));
@ -3215,7 +3213,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
oself = QCC_PR_GetDef(type_entity, "oself", scope, true, 1); oself = QCC_PR_GetDef(type_entity, "oself", scope, true, 1);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], self, oself, NULL)); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], self, oself, NULL));
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], ed, self, NULL)); //return to our old self. boom boom. QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], ed, self, NULL)); //return to our old self. boom boom.
QCC_PR_SimpleStatement(OP_CALL0, constructor->ofs, 0, 0); QCC_PR_SimpleStatement(OP_CALL0, constructor->ofs, 0, 0, false);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], oself, self, NULL)); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], oself, self, NULL));
} }
@ -3887,10 +3885,10 @@ QCC_def_t *QCC_PR_Term (void)
switch (e->type->type) switch (e->type->type)
{ {
case ev_integer: case ev_integer:
QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e); QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e, false);
break; break;
case ev_float: case ev_float:
QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e); QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e, false);
break; break;
default: default:
QCC_PR_ParseError(ERR_BADPLUSPLUSOPERATOR, "++ operator on unsupported type"); QCC_PR_ParseError(ERR_BADPLUSPLUSOPERATOR, "++ operator on unsupported type");
@ -3909,10 +3907,10 @@ QCC_def_t *QCC_PR_Term (void)
switch (e->type->type) switch (e->type->type)
{ {
case ev_integer: case ev_integer:
QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e); QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e, false);
break; break;
case ev_float: case ev_float:
QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e); QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e, false);
break; break;
default: default:
QCC_PR_ParseError(ERR_BADPLUSPLUSOPERATOR, "-- operator on unsupported type"); QCC_PR_ParseError(ERR_BADPLUSPLUSOPERATOR, "-- operator on unsupported type");
@ -4267,9 +4265,9 @@ QCC_def_t *QCC_PR_Expression (int priority)
optres_logicops++; optres_logicops++;
st = &statements[numstatements]; st = &statements[numstatements];
if (*op->name == '&') //statement 3 because we don't want to optimise this into if from not ifnot if (*op->name == '&') //statement 3 because we don't want to optimise this into if from not ifnot
QCC_PR_Statement3(&pr_opcodes[OP_IFNOT], e, NULL, NULL); QCC_PR_Statement3(&pr_opcodes[OP_IFNOT], e, NULL, NULL, false);
else else
QCC_PR_Statement3(&pr_opcodes[OP_IF], e, NULL, NULL); QCC_PR_Statement3(&pr_opcodes[OP_IF], e, NULL, NULL, false);
} }
e2 = QCC_PR_Expression (priority-1); e2 = QCC_PR_Expression (priority-1);
@ -4439,16 +4437,16 @@ QCC_def_t *QCC_PR_Expression (int priority)
//return original loaded (which is not at the same offset as the pointer we store to) //return original loaded (which is not at the same offset as the pointer we store to)
e2 = QCC_GetTemp(type_float); e2 = QCC_GetTemp(type_float);
e3 = QCC_GetTemp(type_pointer); e3 = QCC_GetTemp(type_pointer);
QCC_PR_SimpleStatement(OP_ADDRESS, statements[numstatements-1].a, statements[numstatements-1].b, e3->ofs); QCC_PR_SimpleStatement(OP_ADDRESS, statements[numstatements-1].a, statements[numstatements-1].b, e3->ofs, false);
if (e->type->type == ev_float) if (e->type->type == ev_float)
{ {
QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e2); QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e2, false);
QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], e2, e3, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], e2, e3, NULL, false);
} }
else if (e->type->type == ev_integer) else if (e->type->type == ev_integer)
{ {
QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e2); QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e2, false);
QCC_PR_Statement3(&pr_opcodes[OP_STOREP_I], e2, e3, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STOREP_I], e2, e3, NULL, false);
} }
else else
{ {
@ -4467,8 +4465,8 @@ QCC_def_t *QCC_PR_Expression (int priority)
qcc_usefulstatement=true; qcc_usefulstatement=true;
e2 = QCC_GetTemp(type_float); e2 = QCC_GetTemp(type_float);
QCC_PR_Statement3(&pr_opcodes[OP_STORE_F], e, e2, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STORE_F], e, e2, NULL, false);
QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e); QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e, false);
QCC_FreeTemp(e); QCC_FreeTemp(e);
e = e2; e = e2;
} }
@ -4478,8 +4476,8 @@ QCC_def_t *QCC_PR_Expression (int priority)
qcc_usefulstatement=true; qcc_usefulstatement=true;
e2 = QCC_GetTemp(type_integer); e2 = QCC_GetTemp(type_integer);
QCC_PR_Statement3(&pr_opcodes[OP_STORE_I], e, e2, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STORE_I], e, e2, NULL, false);
QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e); QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e, false);
QCC_FreeTemp(e); QCC_FreeTemp(e);
e = e2; e = e2;
} }
@ -4501,16 +4499,16 @@ QCC_def_t *QCC_PR_Expression (int priority)
//return original loaded (which is not at the same offset as the pointer we store to) //return original loaded (which is not at the same offset as the pointer we store to)
e2 = QCC_GetTemp(type_float); e2 = QCC_GetTemp(type_float);
e3 = QCC_GetTemp(type_pointer); e3 = QCC_GetTemp(type_pointer);
QCC_PR_SimpleStatement(OP_ADDRESS, statements[numstatements-1].a, statements[numstatements-1].b, e3->ofs); QCC_PR_SimpleStatement(OP_ADDRESS, statements[numstatements-1].a, statements[numstatements-1].b, e3->ofs, false);
if (e->type->type == ev_float) if (e->type->type == ev_float)
{ {
QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e2); QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e2, false);
QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], e2, e3, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], e2, e3, NULL, false);
} }
else if (e->type->type == ev_integer) else if (e->type->type == ev_integer)
{ {
QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e2); QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e2, false);
QCC_PR_Statement3(&pr_opcodes[OP_STOREP_I], e2, e3, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STOREP_I], e2, e3, NULL, false);
} }
else else
{ {
@ -4526,8 +4524,8 @@ QCC_def_t *QCC_PR_Expression (int priority)
qcc_usefulstatement=true; qcc_usefulstatement=true;
e2 = QCC_GetTemp(type_float); e2 = QCC_GetTemp(type_float);
QCC_PR_Statement3(&pr_opcodes[OP_STORE_F], e, e2, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STORE_F], e, e2, NULL, false);
QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e); QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e, false);
QCC_FreeTemp(e); QCC_FreeTemp(e);
e = e2; e = e2;
} }
@ -4537,8 +4535,8 @@ QCC_def_t *QCC_PR_Expression (int priority)
qcc_usefulstatement=true; qcc_usefulstatement=true;
e2 = QCC_GetTemp(type_integer); e2 = QCC_GetTemp(type_integer);
QCC_PR_Statement3(&pr_opcodes[OP_STORE_I], e, e2, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STORE_I], e, e2, NULL, false);
QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e); QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e, false);
QCC_FreeTemp(e); QCC_FreeTemp(e);
e = e2; e = e2;
} }
@ -4803,7 +4801,7 @@ void QCC_PR_ParseStatement (void)
statement_linenums[numstatements] = linenum[i]; statement_linenums[numstatements] = linenum[i];
statements[numstatements++] = temp[i]; statements[numstatements++] = temp[i];
} }
QCC_PR_SimpleStatement(OP_GOTO, patch2 - &statements[numstatements], 0, 0); QCC_PR_SimpleStatement(OP_GOTO, patch2 - &statements[numstatements], 0, 0, false);
if (patch1) if (patch1)
patch1->b = &statements[numstatements] - patch1; patch1->b = &statements[numstatements] - patch1;
@ -5518,28 +5516,28 @@ void QCC_PR_ParseState (void)
t1 = QCC_PR_Statement(&pr_opcodes[OP_LT], frame, s1, NULL); t1 = QCC_PR_Statement(&pr_opcodes[OP_LT], frame, s1, NULL);
t2 = QCC_PR_Statement(&pr_opcodes[OP_GT], frame, def, NULL); t2 = QCC_PR_Statement(&pr_opcodes[OP_GT], frame, def, NULL);
t1 = QCC_PR_Statement(&pr_opcodes[OP_OR], t1, t2, NULL); t1 = QCC_PR_Statement(&pr_opcodes[OP_OR], t1, t2, NULL);
QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs, 2, 0); QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs, 2, 0, false);
QCC_FreeTemp(t1); QCC_FreeTemp(t1);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL)); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL));
QCC_PR_SimpleStatement(OP_GOTO, t1->ofs, 13, 0); QCC_PR_SimpleStatement(OP_GOTO, t1->ofs, 13, 0, false);
t1 = QCC_PR_Statement(&pr_opcodes[OP_GE], def, s1, NULL); t1 = QCC_PR_Statement(&pr_opcodes[OP_GE], def, s1, NULL);
QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs, 7, 0); QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs, 7, 0, false);
QCC_FreeTemp(t1); //this block is the 'it's in a forwards direction' QCC_FreeTemp(t1); //this block is the 'it's in a forwards direction'
QCC_PR_SimpleStatement(OP_ADD_F, frame->ofs, QCC_MakeFloatDef(1)->ofs, frame->ofs); QCC_PR_SimpleStatement(OP_ADD_F, frame->ofs, QCC_MakeFloatDef(1)->ofs, frame->ofs, false);
t1 = QCC_PR_Statement(&pr_opcodes[OP_GT], frame, def, NULL); t1 = QCC_PR_Statement(&pr_opcodes[OP_GT], frame, def, NULL);
QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs,2, 0); QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs,2, 0, false);
QCC_FreeTemp(t1); QCC_FreeTemp(t1);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL)); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL));
QCC_UnFreeTemp(frame); QCC_UnFreeTemp(frame);
if (cycle_wrapped) if (cycle_wrapped)
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL)); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL));
QCC_PR_SimpleStatement(OP_GOTO, 6, 0, 0); QCC_PR_SimpleStatement(OP_GOTO, 6, 0, 0, false);
//reverse animation. //reverse animation.
QCC_PR_SimpleStatement(OP_SUB_F, frame->ofs, QCC_MakeFloatDef(1)->ofs, frame->ofs); QCC_PR_SimpleStatement(OP_SUB_F, frame->ofs, QCC_MakeFloatDef(1)->ofs, frame->ofs, false);
t1 = QCC_PR_Statement(&pr_opcodes[OP_LT], frame, s1, NULL); t1 = QCC_PR_Statement(&pr_opcodes[OP_LT], frame, s1, NULL);
QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs,2, 0); QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs,2, 0, false);
QCC_FreeTemp(t1); QCC_FreeTemp(t1);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], def, frame, NULL)); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], def, frame, NULL));
QCC_UnFreeTemp(frame); QCC_UnFreeTemp(frame);
@ -5595,7 +5593,7 @@ void QCC_PR_ParseAsm(void)
{ {
patch1 = &statements[numstatements]; patch1 = &statements[numstatements];
QCC_PR_Statement3(&pr_opcodes[op], NULL, NULL, NULL); QCC_PR_Statement3(&pr_opcodes[op], NULL, NULL, NULL, true);
if (pr_token_type == tt_name) if (pr_token_type == tt_name)
{ {
@ -5614,7 +5612,7 @@ void QCC_PR_ParseAsm(void)
patch1 = &statements[numstatements]; patch1 = &statements[numstatements];
a = QCC_PR_ParseValue(pr_classtype); a = QCC_PR_ParseValue(pr_classtype);
QCC_PR_Statement3(&pr_opcodes[op], a, NULL, NULL); QCC_PR_Statement3(&pr_opcodes[op], a, NULL, NULL, true);
if (pr_token_type == tt_name) if (pr_token_type == tt_name)
{ {
@ -5634,7 +5632,7 @@ void QCC_PR_ParseAsm(void)
a = QCC_PR_ParseValue(pr_classtype); a = QCC_PR_ParseValue(pr_classtype);
b = QCC_PR_ParseValue(pr_classtype); b = QCC_PR_ParseValue(pr_classtype);
QCC_PR_Statement3(&pr_opcodes[op], a, b, NULL); QCC_PR_Statement3(&pr_opcodes[op], a, b, NULL, true);
if (pr_token_type == tt_name) if (pr_token_type == tt_name)
{ {
@ -5664,7 +5662,7 @@ void QCC_PR_ParseAsm(void)
else else
c=NULL; c=NULL;
QCC_PR_Statement3(&pr_opcodes[op], a, b, c); QCC_PR_Statement3(&pr_opcodes[op], a, b, c, true);
} }
QCC_PR_Expect(";"); QCC_PR_Expect(";");
@ -6611,8 +6609,8 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array)
temp = QCC_PR_GetDef(type_float, "div3___", func, true, 1); temp = QCC_PR_GetDef(type_float, "div3___", func, true, 1);
locals_end = numpr_globals; locals_end = numpr_globals;
df->locals = locals_end - df->parm_start; df->locals = locals_end - df->parm_start;
QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatDef(3), temp); QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatDef(3), temp, false);
QCC_PR_Statement3(pr_opcodes+OP_BITAND, temp, temp, temp);//round down to int QCC_PR_Statement3(pr_opcodes+OP_BITAND, temp, temp, temp, false);//round down to int
QCC_PR_ArrayRecurseDivideUsingVectors(array, temp, 0, (array->arraysize+2)/3); //round up QCC_PR_ArrayRecurseDivideUsingVectors(array, temp, 0, (array->arraysize+2)/3); //round up
@ -6669,12 +6667,12 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
QCC_PR_Statement(pr_opcodes+OP_IFNOT, fasttrackpossible, NULL, &st); QCC_PR_Statement(pr_opcodes+OP_IFNOT, fasttrackpossible, NULL, &st);
//fetch_gbl takes: (float size, variant array[]), float index, variant pos //fetch_gbl takes: (float size, variant array[]), float index, variant pos
//note that the array size is coded into the globals, one index before the array. //note that the array size is coded into the globals, one index before the array.
def->ofs--; // def->ofs--;
if (def->type->size >= 3) if (def->type->size >= 3)
QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_V], def, index, &def_ret); QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_V], def, index, &def_ret, true);
else else
QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_F], def, index, &def_ret); QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_F], def, index, &def_ret, true);
def->ofs++; // def->ofs++;
//finish the jump //finish the jump
st->b = &statements[numstatements] - st; st->b = &statements[numstatements] - st;
@ -6697,19 +6695,19 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatDef(0), 0, &st); QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatDef(0), 0, &st);
div3->references++; div3->references++;
QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index); QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index, false);
QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatDef(3), div3); QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatDef(3), div3, false);
QCC_PR_Statement3(pr_opcodes+OP_BITAND, div3, div3, intdiv3); QCC_PR_Statement3(pr_opcodes+OP_BITAND, div3, div3, intdiv3, false);
QCC_PR_Statement3(pr_opcodes+OP_STORE_F, index, &def_parms[0], NULL); QCC_PR_Statement3(pr_opcodes+OP_STORE_F, index, &def_parms[0], NULL, false);
QCC_PR_Statement3(pr_opcodes+OP_CALL1, vectortrick, NULL, NULL); QCC_PR_Statement3(pr_opcodes+OP_CALL1, vectortrick, NULL, NULL, false);
vectortrick->references++; vectortrick->references++;
ret = QCC_PR_GetDef(type_vector, "vec__", pr_scope, true, 1); ret = QCC_PR_GetDef(type_vector, "vec__", pr_scope, true, 1);
ret->references+=4; ret->references+=4;
QCC_PR_Statement3(pr_opcodes+OP_STORE_V, &def_ret, ret, NULL); QCC_PR_Statement3(pr_opcodes+OP_STORE_V, &def_ret, ret, NULL, false);
div3 = QCC_PR_Statement(pr_opcodes+OP_MUL_F, intdiv3, QCC_MakeFloatDef(3), NULL); div3 = QCC_PR_Statement(pr_opcodes+OP_MUL_F, intdiv3, QCC_MakeFloatDef(3), NULL);
QCC_PR_Statement3(pr_opcodes+OP_SUB_F, index, div3, index); QCC_PR_Statement3(pr_opcodes+OP_SUB_F, index, div3, index, false);
QCC_FreeTemp(div3); QCC_FreeTemp(div3);
eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(0+0.5f), NULL); eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(0+0.5f), NULL);
@ -6734,7 +6732,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
} }
else else
{ {
QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index); QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index, false);
QCC_PR_ArrayRecurseDivideRegular(def, index, 0, def->arraysize); QCC_PR_ArrayRecurseDivideRegular(def, index, 0, def->arraysize);
} }
@ -6826,21 +6824,21 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
QCC_PR_Statement(pr_opcodes+OP_IFNOT, fasttrackpossible, NULL, &st); QCC_PR_Statement(pr_opcodes+OP_IFNOT, fasttrackpossible, NULL, &st);
//note that the array size is coded into the globals, one index before the array. //note that the array size is coded into the globals, one index before the array.
QCC_PR_Statement3(&pr_opcodes[OP_CONV_FTOI], index, NULL, index); //address stuff is integer based, but standard qc (which this accelerates in supported engines) only supports floats QCC_PR_Statement3(&pr_opcodes[OP_CONV_FTOI], index, NULL, index, true); //address stuff is integer based, but standard qc (which this accelerates in supported engines) only supports floats
QCC_PR_SimpleStatement (OP_BOUNDCHECK, index->ofs, 0, ((int*)qcc_pr_globals)[def->ofs-1]);//annoy the programmer. :p QCC_PR_SimpleStatement (OP_BOUNDCHECK, index->ofs, ((int*)qcc_pr_globals)[def->ofs-1], 0, true);//annoy the programmer. :p
if (def->type->size != 1)//shift it upwards for larger types if (def->type->size != 1)//shift it upwards for larger types
QCC_PR_Statement3(&pr_opcodes[OP_MUL_I], index, QCC_MakeIntDef(def->type->size), index); QCC_PR_Statement3(&pr_opcodes[OP_MUL_I], index, QCC_MakeIntDef(def->type->size), index, true);
QCC_PR_Statement3(&pr_opcodes[OP_GLOBALADDRESS], def, index, index); //comes with built in add QCC_PR_Statement3(&pr_opcodes[OP_GLOBALADDRESS], def, index, index, true); //comes with built in add
if (def->type->size >= 3) if (def->type->size >= 3)
QCC_PR_Statement3(&pr_opcodes[OP_STOREP_V], value, index, NULL); //*b = a QCC_PR_Statement3(&pr_opcodes[OP_STOREP_V], value, index, NULL, true); //*b = a
else else
QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], value, index, NULL); QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], value, index, NULL, true);
//finish the jump //finish the jump
st->b = &statements[numstatements] - st; st->b = &statements[numstatements] - st;
} }
QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index); QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index, false);
QCC_PR_ArraySetRecurseDivide(def, index, value, 0, def->arraysize); QCC_PR_ArraySetRecurseDivide(def, index, value, 0, def->arraysize);
QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL); QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL);

View File

@ -1427,6 +1427,7 @@ void QCC_PR_BeginCompilation (void *memory, int memsize)
pr.def_tail = &pr.def_head; pr.def_tail = &pr.def_head;
QCC_PR_ResetErrorScope(); QCC_PR_ResetErrorScope();
pr_scope = NULL;
/* numpr_globals = RESERVED_OFS; /* numpr_globals = RESERVED_OFS;