Code archives/Miscellaneous/acidstub

This code has been declared by its author to be Public Domain code.

Download source code

acidstub by skidracer
(Posted 23 years ago)
C++ programmers wishing to extend their Blitz projects may find this tool useful.

Thanks to VERFUM for the original idea.
; acidstub.bb
; by simon@nitrologic.net

; builds external interface for a Blitz project using .dll callback mechanism
; creates both the bootstrap.bb and the acidstub.h header file For use by external project
; link to your own blitz functions by publishing a .decls file for your blitz routines

; inputs:	a valid blitzpath 
; outputs:	bootstrap.bb and acidstub.h file 

; build instructions
; 1. run acidstub
; 2. build mygame.dll from mygame.cpp 
; 3. run bootstrap.bb

; example dll project source
;
;	//acidstub.cpp
;
;	#define WIN32_LEAN_AND_MEAN
;	#include <windows.h>
;
;	DWORD WINAPI StubMain(void *);
;
;	#include "acidstub.h"
;
;	DWORD WINAPI StubMain(void *)
;	{
;		Graphics(640,480,0,2);
;		MouseWait();
;		End();
;		return 0;
;	}

Const dllname$="acidstub"
Const blitzpath$="c:\blitz\blitz3d\"

; dump keywords

blitzcc$=Chr$(34)+blitzpath+"bin\blitzcc"+Chr$(34)
f=WriteFile("stublist.bat")
WriteLine f,"set blitzpath="+blitzpath$
WriteLine f,blitzcc+" +k "+">"+"commands.txt"
CloseFile f
ExecFile "stublist"
Delay (500)

; process dump

Const NULLTYPE=0
Const INTTYPE=1
Const FLOATTYPE=2
Const STRINGTYPE=3

Type command
	Field	name$,help$
	Field	args
	Field	arg[10]
End Type

Function CommandInvoke$(c.command)
	Local	a$,b$,v$
	a$=""
	For i=1 To c\args
		Select c\arg[i]
			Case INTTYPE:v$="v"+Chr$(96+i):a$=a$+v$+"=argint():"
			Case FLOATTYPE:v$="f"+Chr$(96+i)+"#":a$=a$+v$+"=argfloat():"
			Case STRINGTYPE:v$="s"+Chr$(96+i)+"$":a$=a$+v$+"=argstring():"
		End Select
		b$=b$+v$
		If i<c\args b$=b$+","
	Next
	Select c\arg[0]
		Case NULLTYPE:a$=a$+c\name+" "+b$
		Case INTTYPE::a$=a$+"PokeInt(out,0,"+c\name+"("+b$+"))"
		Case FLOATTYPE:a$=a$+"PokeFloat(out,0,"+c\name+"("+b$+"))"
		Case STRINGTYPE:a$=a$+"PokeString(out,0,"+c\name+"("+b$+"))"
	End Select
	Return a$
End Function

Function CommandDef$(c.command,id)
	Local	a$,d$,v$,r$,dd$,vv$
	Select c\arg[0]
		Case NULLTYPE:a$="void "
		Case INTTYPE::a$="int ":r$="return *(int*)result;"
		Case FLOATTYPE:a$="float ":r$="return *(float*)result;"
		Case STRINGTYPE:a$="char *":r$="return (char*)result;"
	End Select
	vv$=id
	For i=1 To c\args
		Select c\arg[i]
			Case INTTYPE:v$="v"+Chr$(96+i):d$="int "+v$
			Case FLOATTYPE:v$="f"+Chr$(96+i):d$="float "+v$
			Case STRINGTYPE:v$="s"+Chr$(96+i):d$="char *"+v$	
		End Select
		vv$=vv$+","+v$
		dd$=dd$+d$
		If i<c\args dd$=dd$+","
	Next
	a$=a$+c\name+"("+dd$+") {invoke("+vv$+");"
	a$=a$+r$
	a$=a$+"}"
	Return a$
End Function

Function CreateCommand.command(d$)
	c.command=New command
	c\help=d$	
	p=Instr(d$,"(")
	If p>2
		q=p-1
		r$=Mid$(d$,p-2,1)
		t=INTTYPE
		If r$="#" t=FLOATTYPE:q=p-2
		If r$="$" t=STRINGTYPE:q=p-2
		c\arg[0]=t
		c\name=Mid$(d$,1,q-1)
		p=p+1
	Else
		p=Instr(d$," ")
		If p=0 c\name=d$:Return c		;c\arg[0]=INTTYPE:Return c
		c\name=Mid$(d$,1,p-1)
	EndIf

	p=Instr(d$," ")
	If (p) d$=Mid$(d$,p)
	d$=Replace$(d$,"(","")
	d$=Replace$(d$,")","")
	d$=Replace$(d$,"[","")
	d$=Replace$(d$,"]","")
	d$=Replace$(d$," ","")
	p=1
	If d$="" Return c

	While True
		q=Instr(d$,",",p)
		If q=0 q=Len(d$)+1
		If q=0 Return c
		r$=Mid$(d$,q-1,1)
		t=INTTYPE
		If r$="#" t=FLOATTYPE
		If r$="$" t=STRINGTYPE
		c\args=c\args+1
		c\arg[c\args]=t
		p=q+1
		If p>Len(d$) Or c\args=10 Return c
	Wend
End Function

f=ReadFile("commands.txt")
If f=0 Input("blitzcc command dump failure"):End

i=0
While Not Eof(f)
	cmd$=ReadLine(f)
	If i>58 c.command=CreateCommand(cmd$)
	i=i+1
Wend
CloseFile f

; create bootstrap.bb file

f=WriteFile("bootstrap.bb")
If f=0 Input("failed create bootstrap.bb file"):End
While True
	Read a$
	a$=Replace$(a$,"'",Chr$(34))
	If a$="" Exit
	WriteLine f,a$
Wend
i=0
For c.command=Each command
	a$="Case "+i+":"+CommandInvoke(c)
	WriteLine f,Chr$(9)+a$
	i=i+1
Next
WriteLine f,"End Select"
WriteLine f,"Wend"
CloseFile f

; create blitzstub.h file

f=WriteFile("acidstub.h")
If f=0 Input("failed to create acidstub.h file"):End
While True
	Read a$
	a$=Replace$(a$,"'",Chr$(34))
	If a$="" Exit
	WriteLine f,a$
Wend
i=0
For c.command=Each command
	a$=CommandDef(c,i)
	WriteLine f,a$
	i=i+1
Next
CloseFile f

Input "CreateStub Complete"
End


; bootstrap.bb core

Data "; bootstrap.bb"
Data "; launchpad for "+dllname$+".dll"
Data " "
Data "Function PokeString(bank,offset,a$)"
Data "	l=Len(a$)"
Data "	If (l>4000) l=4000"
Data "	PokeInt bank,offset,l"
Data "	For i=1 To l"
Data "		PokeByte bank,offset+3+i,Asc(Mid$(a$,i,1))"
Data "	Next"
Data "End Function"
Data " "
Data "Function argstring$()"
Data "	l=PeekInt(in,arg)"
Data "	arg=arg+4"
Data "	If (l>4000) l=4000"
Data "	For i=1 To l"
Data "		a$=a$+Chr$(PeekByte(in,arg))"
Data "		arg=arg+1"
Data "	Next"
Data "	Return a$"
Data "End Function"
Data " "
Data "Function argint()"
Data "	arg=arg+4"
Data "	Return PeekInt(in,arg-4)"
Data "End Function"
Data " "
Data "Function argfloat()"
Data "	arg=arg+4"
Data "	Return PeekFloat(in,arg-4)"
Data "End Function"
Data " "
Data "Global in=CreateBank(4096)"
Data "Global out=CreateBank(4096)"
Data "Global arg"
Data " "
Data "While True"
Data "	res=CallDLL('"+dllname$+"','call',in,out)"
Data "	arg=0"
Data "	Select res"
Data ""

; acidstub.h core

Data "// acidstub.h"
Data " "
Data "DWORD WINAPI StubMain(void *);"
Data "const void	*result;"
Data "char		*argptr;"
Data "int			stubcmd;"
Data "void arg(char *a);"
Data "void arg(int a) {*(int*)argptr=a;argptr+=4;}"
Data "void arg(float a) {*(float*)argptr=a;argptr+=4;}"
Data "void invoke(int cmd);"
Data "void invoke(int cmd,int i0) {arg(i0);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1) {arg(i0);arg(i1);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,int i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,int i2,int i3) {arg(i0);arg(i1);arg(i2);arg(i3);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,int i2,int i3,int i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,int i2,int i3,int i4,int i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,int i2,int i3,int i4,int i5,int i6) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,int i2,int i3,int i4,int i5,int i6,int i7) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);arg(i7);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,float i2,int i3,int i4,int i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,float i2,float i3,int i4,int i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,float i2,float i3,float i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,float i2,int i3,float i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,int i2,float i3,float i4,float i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,float i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,int i2,float i3,int i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,float i2,float i3,float i4,int i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,char *c1) {arg(i0);arg(c1);invoke(cmd);}"
Data "void invoke(int cmd,int i0,char *c1,int i2) {arg(i0);arg(c1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,int i0,char *i1,int i2,int i3) {arg(i0);arg(i1);arg(i2);arg(i3);invoke(cmd);}"
Data "void invoke(int cmd,int i0,char *i1,int i2,int i3,int i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,char *i2,int i3,int i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1) {arg(i0);arg(i1);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,int i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3) {arg(i0);arg(i1);arg(i2);arg(i3);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,float i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,float i4,float i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,float i4,float i5,float i6) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,int i3,int i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,int i4,int i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,int i3,int i4,int i5,int i6,int i7) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);arg(i7);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,int i3,int i4,int i5,int i6) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,float i4,float i5,int i6,int i7) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);arg(i7);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,int i4,float i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,int i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,float i2,int i3,int i4,float i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,int i1,float i2,float i3,float i4,float i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,float i4,float i5,float i6,float i7) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);arg(i7);invoke(cmd);}"
Data "void invoke(int cmd,int i0,float i1,float i2,float i3,float i4,float i5,float i6,int i7) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);arg(i7);invoke(cmd);}"
Data "void invoke(int cmd,float i0) {arg(i0);invoke(cmd);}"
Data "void invoke(int cmd,float i0,float i1) {arg(i0);arg(i1);invoke(cmd);}"
Data "void invoke(int cmd,float i0,float i1,float i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,float i0,float i1,float i2,int i3,int i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,float i0,float i1,float i2,float i3,float i4,int i5,int i6) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);invoke(cmd);}"
Data "void invoke(int cmd,float i0,float i1,float i2,float i3,float i4,float i5,float i6) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);invoke(cmd);}"
Data "void invoke(int cmd,char *c0) {arg(c0);invoke(cmd);}"
Data "void invoke(int cmd,char *c0,char *c1) {arg(c0);arg(c1);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,int i1,int i2,int i3,int i4,int i5) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,float i1,float i2,float i3,float i4,float i5,float i6,float i7) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);arg(i7);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,float i1,float i2,float i3,float i4,float i5,float i6,float i7,float i8,float i9) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);arg(i5);arg(i6);arg(i7);arg(i8);arg(i9);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,int i1) {arg(i0);arg(i1);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,int i1,int i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,int i1,int i2,int i3) {arg(i0);arg(i1);arg(i2);arg(i3);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,int i1,int i2,int i3,int i4) {arg(i0);arg(i1);arg(i2);arg(i3);arg(i4);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,char *i1,char *i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,float i1,int i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,char *i1,int i2) {arg(i0);arg(i1);arg(i2);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,char *i1,int i2,int i3) {arg(i0);arg(i1);arg(i2);arg(i3);invoke(cmd);}"
Data "void invoke(int cmd,char *i0,int i1,float i2,float i3) {arg(i0);arg(i1);arg(i2);arg(i3);invoke(cmd);}"
Data "DWORD		threadid=0;"
Data "HANDLE		thread,callevent,resevent;"
Data "int __stdcall DllMain(int,int,void *)"
Data "{"
Data "	return 1;"
Data "}"
Data "extern 'C' _declspec(dllexport) int _cdecl call(const void *in,int ibytes,void *out,int outbytes)"
Data "{"
Data "	DWORD		res;"
Data "	result=out;"
Data "	argptr=(char*)in;"
Data "	if (threadid==0)"
Data "	{"
Data "		callevent=CreateEvent(0,0,0,0);"
Data "		resevent=CreateEvent(0,0,0,0);"
Data "		thread=CreateThread(0,0,StubMain,0,0,&threadid);"
Data "	}"
Data "	else"
Data "	{"
Data "		SetEvent(resevent);"
Data "	}"
Data "	while (true)"
Data "	{"
Data "		res=WaitForSingleObject(callevent,INFINITE);"
Data "		if (res==WAIT_OBJECT_0) break;"
Data "	}"
Data "	return stubcmd;"
Data "}"
Data "void invoke(int cmd)"
Data "{"
Data "	DWORD	res;"
Data "	stubcmd=cmd;"
Data "	SetEvent(callevent);"
Data "	while (true)"
Data "	{"
Data "		res=WaitForSingleObject(resevent,INFINITE);"
Data "		if (res==WAIT_OBJECT_0) break;"
Data "	}"
Data "}"
Data "void arg(char *a)"
Data "{"
Data "	int		n;"
Data "	char	*p;"
Data "	p=argptr+4;n=0;"
Data "	while (*p++=*a++)"
Data "	{"
Data "		n++;"
Data "		if (n==4000) {*p++=0;break;}"
Data "	}"
Data "	*(int*)argptr=n-1;"
Data "	argptr=p;"
Data "}"
Data ""