Pages:
1
2 |
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
Tutorial?
Hey Mike,
Is there any chance of a tutorial on how to put together and use one of these DLL things?
My understanding of how it all works under the hood is zero and, to be honest, I'm seriously daunted at the thought of trying to figure it out myself
so it would be great if you could make a basic walk-through with respect to getting things up and running,
I'd definitely like to start contributing more both with DLLs and the source code itself.
|
|
MikeDX
|
|
DLLs are fairly straightforward regarding the compilation.
It's easy to compile the examples especially on Linux.
Clone the div source tree (not actually necessary as the dll code is seperate)
In tools there is a makedll.bat you can use to compile an example e.g.
tools/makedll.bat dll/hboy.c hboy.so
Should create a hboy.so "dll" which will autoload on any div program being run
Please forgive the accuracy of this info, I'm replying from my phone and going mostly on memory.
The examples are definitely the place to start but if you have specific questions I'm happy to help.
Also creating DLLs is definitely a "way in" to contributing to the main div codebase as quite a few functions started off as plugins and got
integrated into the main codebase (network, mode8)
|
|
tvault
DIV Newbie
Posts: 3
Registered: 18-12-2016
Member Is Offline
|
|
Hi, I used DIV many years ago and decided to get back onboard as I always enjoyed using it.
If you're interested I found my copy of DIV and installed it using DOSbox, found a nice tutorial
from Daniel Navarro Medrano.
I hope this is useful to you:
Code: |
DIV Games Studio - Dinamic Link Libraries
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
This document shows you all the needed information to build your own DLL's for
DIV Games Studio
- "What is a DLL?"
A DLL (Dynamic Link Library) is a piece of code of a program that can be
merged with another program in execution time, which contains functions or
procedures that can be used on the program.
- ¨What are DLL's for?"
DLL's are useful to extend the programming language capabilities of DIV, so
you can modify partially the way they work. These allow you to implement pieces
of code in the C language, to be used or called from within DIV.
- ¨Types of DLL's"
Basically, there are three types of DLL's that can be built for DIV. The
first ones are screen savers, the second are autoloading and the
third ones add new functions to the language.
General Instructions.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
This is procedure only recommended for EXPERT programmers on C language, who
own the "WATCOM C++ Compiler". Other compilers are available, of course, but
since we haven't tried them for this purpose, we cannot guarantee that they
will work...
First thing to do is add the following text to the WLSYSTEM.LNK file of
Watcom (which can be found on the BINB\ directory of that compiler).
system begin div_dll
option osname='DIV DLL'
libpath %WATCOM%\lib386
libpath %WATCOM%\lib386\dos
format windows nt dll ^
end
The format of the code used is the one of the Windows NT DLL's, and this is the
way you inform Watcom to generate this kind of code.
After this, you should include the header file named DIV.H, which is included
on this directory. On this header file are the defined variables and basic
functions with which you can use. In addition, this file contains a set
of "#define" instructions, accessing the internal variables of DIV32RUN,
which is the module that has all the internal functions and routines of
DIV Games Studio.
Several examples are included, the most basic being:
DEMO0.CPP - Basic example of a screensaver with DIV's games.
DEMO1.CPP - Basic example of an autoload DLL.
DEMO2.CPP - Basic example of DLL functions.
You may use the batch file named MAKE.BAT to compile these DLL's (if you own
Watcom C++ for DOS) which, if no error is found, generates the corresponding
DLL (with the same name).
Basic rules.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
DLL's must be created in standard C, and they must respect several rules. For
example:
- The "div.h" header must be included on the main module, so the following
definition must be done:
#define GLOBALS
before including the header (#include "div.h"), variables types and basic
structures can be defined, this is for when you build DLL's with several
CPP sources).
- It is not possible to use the functions malloc(), free(), fopen() or fclose()
so you must instead use div_malloc(), div_free(), div_fopen() and div_fclose().
These functions behave exactly the same way than the ones used on C.
- You must always define two functions for the begin and end of the DLL, which
are:
void __export divmain(COMMON_PARAMS) {
GLOBAL_IMPORT();
// Begin of DLL
}
void __export divend(COMMON_PARAMS) {
// End of DLL
}
- Besides functions exported by DIV, you may use most standard C functions,
including its headers.
¨How are DLL's used on the language?"
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
DLL's are divided on two types: normals and autoload.
To use normals, you must indicate on a game the following sentence:
IMPORT "directory\name.dll";
Just after the LOCAL declarations of the main program. You cannot use DLL's from
other languages.
Autoload can be used the same way, or just by copying them into the directory of
the game. They will activate automatically.
For example, if the DEMO0.DLL (the example screen saver) is copied on the
directory of the game made with DIV, this will activate automatically every
time the game is executed. To activate this DLL's while the game is executed
within DIV's environment, you must copy them to the directory where the D.EXE
(the main executable file of DIV) file is placed.
Screen savers (look at demo0.cpp)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
You may define the following functions in a DLL.
ss_init() - To initialize the screen saver (every time it is executed).
ss_frame() - To make operations over the video buffer, before it is dumped.
ss_end() - To terminate the screen saver.
You have as well, the following available variables:
ss_time - To indicate the period of time after which the screen saver will
execute, on hundreds of a second (default is 3000, which is every
30 seconds).
ss_status - To activate and deactivate the screen saver (0-Inactive/1-Active)
ss_exit - It must be set to 1 on ss_frame() to terminate the screen
saver (the system will set it to 1 when the keyboard, the mouse or
the joystick is activated).
A screen saver is included on the SS1.CPP file, which is a little bit more
complex than the DEMO0.CPP. This simulates a sand picture.
Autoload DLL (look at demo1.cpp)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
These DLL's are generally used to substitute some of the internal functions
of DIV for another ones. The functions that can be defined are explained on the
DIV.H file (under the "DIV standard Entry-Points" header).
For a DLL to autoload, you must include the following sentence within the
div_main() function:
Autoload();
Two autoload DLL's are included as examples:
WATER.CPP - Simulates a water effect on the bottom of the screen
HBOY.CPP - Try it with any DIV game!... you will see...
DLL of functions (look at demo2.cpp)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
It is easy to add new functions to the language:
First, you must create the new function on the DLL, which must read its
calling parameters with getparm() (who always returns an int), and at
termination, a value must ALWAYS be returned with retval() (look at demo2.cpp).
After, you must define the function on the DLL:
void __export divlibrary(LIBRARY_PARAMS) { }
and within this, you must make a call to COM_export() for each function that
is added to the language.
COM_export() receives three parameters. The first one is the name that the
function will have, the pointer to that function, and the number of parameters
of the call.
In the programs created with DIV, after making the IMPORT of the DLL, you may
directly use these functions.
¨What can be done?"
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
If you take a look at DIV.H, you will find many things to which you may access
from a DLL, you may create programs that modify variables of the process, that
substitute video routines, or that apply effects in windows, etc...
If you succeed to create a functional DLL, you are free to distribute it as
Shareware or on any other format, even Freeware... which will be best! :)
In any case, we will thank you, if you inform us, through the www.div-arena.com
web site, about your personal success with DIV ;)
We will also thank you any suggestion about DIV Games Studio, and much more if
those suggestions are original and useful. Don't waste your time on asking us
for sound modules, for 3D, or true colour....- we are already working on it!.
Thanks for trying!
Daniel Navarro Medrano
Main programmer of DIV Games Studio
and from
FastTrak Software Publishing
|
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
Hey Tvault, this is interesting. Thanks for posting.
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
Hi Mike
Just a quick question. I've just downloaded the source code and have started looking into this DLL business. I'm confused about the makedll file.
In the tools folder there's a makedll.sh but not a makedll.bat as you stated is that the same thing?
|
|
MikeDX
|
|
Yeah i was sure I'd named it .bat but it is the .sh file
Should work fairly easily
Let me know if you need any help
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
Quote: Originally posted by MikeDX | Yeah i was sure I'd named it .bat but it is the .sh file
Should work fairly easily
Let me know if you need any help |
I NEED HELP
I tried this:
tools/makedll.sh dll/hboy.c hboy.so
but got errors referring to the spectrum and sdlgfx folders in the dll one
|
|
MikeDX
|
|
edit the last line in the file and change it to:
Code: |
gcc $1 -o $2 -funsigned-char -shared -I./dll/ `sdl-config --cflags --libs` -ggdb3 -O3 -fPIC
|
It had been hardcoded to use my working directory and for zxspectrum dll / sdlgfx, neither of which you really need.
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
well that got rid of that problem but I can't see a .so file, Help!
|
|
MikeDX
|
|
interesting
if you run the command manually what do you get
Code: |
gcc dll/hboy.c -o hboy.so -funsigned-char -shared -I./dll/ `sdl-config --cflags --libs` -ggdb3 -O3 -fPIC
ls *.so
|
any errors or warnings or anything?
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
/Desktop/DIV2015$ gcc dll/hboy.c -o hboy.so -funsigned-char -shared -I./dll/ `sdl-config --cflags --libs` -ggdb3 -O3 -fPIC
dll/hboy.c: In function ‘set_video_mode’:
dll/hboy.c:512:32: warning: passing argument 2 of ‘SDL_SetVideoMode’ makes pointer from integer without a cast [-Wint-conversion]
screen = SDL_SetVideoMode(320,200,8,0);
^
In file included from /usr/include/SDL/SDL_mouse.h:32:0,
from /usr/include/SDL/SDL_events.h:35,
from /usr/include/SDL/SDL.h:37,
from dll/hboy.c:8:
/usr/include/SDL/SDL_video.h:384:39: note: expected ‘int *’ but argument is of type ‘int’
extern DECLSPEC SDL_Surface * SDLCALL SDL_SetVideoMode
^
dll/hboy.c: In function ‘divmain’:
dll/hboy.c:697:29: warning: passing argument 2 of ‘SDL_SetVideoMode’ makes pointer from integer without a cast [-Wint-conversion]
screen=SDL_SetVideoMode(320,200,8,0);
^
In file included from /usr/include/SDL/SDL_mouse.h:32:0,
from /usr/include/SDL/SDL_events.h:35,
from /usr/include/SDL/SDL.h:37,
from dll/hboy.c:8:
/usr/include/SDL/SDL_video.h:384:39: note: expected ‘int *’ but argument is of type ‘int’
extern DECLSPEC SDL_Surface * SDLCALL SDL_SetVideoMode
|
|
MikeDX
|
|
That looks fine to me
try it with errors ignored:
Code: |
gcc dll/hboy.c -o hboy.so -w -funsigned-char -shared -I./dll/ `sdl-config --cflags --libs` -ggdb3 -O3 -fPIC
|
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
Hang on! the .so is there, it's in the parent folder. Sorry about that.
Where should it be placed in order to by included in a running prg?
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
Ok. Forget the last question. I managed to figure it out all on my own.
So It looks like everything is working now, Thanks for the help.
By the way how do you post code into a nifty little sub window in these forums (like you just did)?
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
And while I'm being a pain in the neck, do you think could you point me in the direction of the part of the source code which deals with mode 7? I'm
interested to see the exact way DIV calculates the screen projections.
[Edited on 21-12-2016 by dom cook]
|
|
MikeDX
|
|
Dom you know full well I am happy for you to be a pain in the neck
some DLLs are "autoload" which means they will automatically be picked up by DIV, this means put them in the same folder as your prg (or d.exe /
d-LINUX / d-OSX etc). hboy is an example of such a dll.
to post code in a mini window use the code tags
e.g.
[code]
your code here
[/code]
I'm unsure about the mode7 in DIV, let me find that for you.
[Edited on 21-12-2016 by MikeDX]
|
|
MikeDX
|
|
The Mode7 function is called 'pinta_m7' and is located in src/runtime/s.c
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
Thanks dood. and merry Christmas
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
I've think I've found a bug in mode 7 now
The x coordinate of the vanishing point in a screen region ought to be the midpoint in x of the region. This the case for mode7 objects but not for
the plane that's declared in the start_mode 7 function. Instead it looks like it's using the midpoint (in x) of the whole screen.
|
|
MikeDX
|
|
Interesting
I think you can prove or disprove this by making 4 mode 7 regions on a single screen with identical initial views.
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
Here's what I meant, although it seems I had it the wrong way round. It's the objects that focus on the centre of the screen.
This example should draw the object at point 0,0 on each of the m7 planes. (being the top-left corner)
By rotating the camera (keys _a, _d) you can see that it's being draw as if it lay on planes that were centred in x around the screen centre.
Attachment: m7bug.PRG (2kB) This file has been downloaded 1869 times
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
It's only taken me two and a half years but I think I've found this little bug.
It's in the source code so I'm not in a position to fix it but now that you're making more time for DIV Mike, I thought I'd prevail upon you to take a
look. Or Cictec if you're out there.
I might be wrong as I speak neither spanish nor C, but I think the problem is with Line 3057 here: https://github.com/MikeDX/DIV-Games-Studio/blob/master/src/r...
(3057) anchura = vga_an / 2 + (factor * distmax) / (max * 16);
As far as I can tell anchura is passed to the screen x coordinate of the M7 process.
vga_an looks like it refers to the size of a scan line. if that is the case then vga_an /2 is the middle of the screen in the x
direction. In cases where mode 7 is drawn to a region whose centre in x is not the middle of the screen this will be the wrong value. The correct
one being the x value for the middle of the mode 7 region.
Of course, this is admittedly all guess work and I realise that I might well be completely wrong but it at least corresponds with the error as
illustrated in the above example.
Anyway, If one of you boys could take a look, I'd be much obliged.
[Edited on 11-5-2019 by dom cook]
|
|
CicTec
DIV Pro
Posts: 471
Registered: 6-8-2016
Member Is Offline
|
|
Hi dom cook,
The line of the source code you are analyzing refers to the function that takes care of rendering mode7 processes (belonging to all mode7 windows) on
the screen.
vga_an is a variable that stores the width of the game resolution set with SET_MODE, for example if you set the resolution to 640x480, vga_an will be
640 and vga_al will be 480 and so on, then 640/2 = 320 which represents the center of the resolution of the game.
it would be useful to mount a small example that shows the bug that you think exists.
[Edited on 11-5-2019 by CicTec]
|
|
dom cook
Div Pro
Posts: 387
Registered: 4-3-2016
Member Is Offline
|
|
I already did that. Look at the m7bug code 3 posts up from here.
It draws 4 mode7 views in 4 separate screen regions in a typical 4-way split-screen format.
If you rotate the views, using keys _A and _D you will see two red markers rotating around the centre of the screen.
These markers are actually the same mode 7 process drawn in the 4 separate views so we should be seeing 4 of them. Given that the coordinates of this
process are 0,0 (Which corresponds to the top left corner of the mode 7 plane you can see that while the y coordinates are translated correctly, the x
coordinates, are being translated as if the x_centres of all the m7 regions are always the x_centre of the screen.
So yes, in all likelihood vga_an is the culprit here. We need something that relates to individual screen regions. I don't know
what that is going to be. However it's probably worth noting that, given that the y coordinate is being translated correctly, there might be a clue
in the lines of code which deal with the corresponding altura variable.
Here is some pertinent code. (3045-3048)
Code: |
h = (m7 + n)->height - mem[ide + _Height];
altura = (h * (max - factor)) / (max); // in pix/4
altura = im7[n].y + im7[n].al / 2 + (h - altura) / 4; // in pix
altura += (m7 + n)->horizon - im7[n].al / 2;
|
I'm thinking that the variable n is probably the m7 number. Notably, there is no reference to this in the line which calculates the x
coordinate.
Any ideas?
My best guess is that there's a variable out there called im7[n].an and subsituting it for vga_an in the alledged
offending line might just help solve the problem. This would account for the width of the region, to account for its start position we might try
im7[n].x
(we can already see that there is an im7[n].y)
My suggested correction would be this:
anchura = im7[n].x + im7[n].an/2 + (factor * distmax) / (max * 16);
[Edited on 11-5-2019 by dom cook]
|
|
CicTec
DIV Pro
Posts: 471
Registered: 6-8-2016
Member Is Offline
|
|
Quote: Originally posted by dom cook | I already did that. Look at the m7bug code 3 posts up from here.
It draws 4 mode7 views in 4 separate screen regions in a typical 4-way split-screen format.
If you rotate the views, using keys _A and _D you will see two red markers rotating around the centre of the screen.
These markers are actually the same mode 7 process drawn in the 4 separate views so we should be seeing 4 of them. Given that the coordinates of this
process are 0,0 (Which corresponds to the top left corner of the mode 7 plane you can see that while the y coordinates are translated correctly, the x
coordinates, are being translated as if the x_centres of all the m7 regions are always the x_centre of the screen.
|
Please post this example to be able to try and verify the actual presence of bugs
Quote: Originally posted by dom cook |
So yes, in all likelihood vga_an is the culprit here. We need something that relates to individual screen regions. I don't know
what that is going to be. However it's probably worth noting that, given that the y coordinate is being translated correctly, there might be a clue
in the lines of code which deal with the corresponding altura variable.
|
Based on the example above (to be tested with the real example), the culprit of the bug could be vga_an
Quote: Originally posted by dom cook |
Here is some pertinent code. (3045-3048)
Code: |
h = (m7 + n)->height - mem[ide + _Height];
altura = (h * (max - factor)) / (max); // in pix/4
altura = im7[n].y + im7[n].al / 2 + (h - altura) / 4; // in pix
altura += (m7 + n)->horizon - im7[n].al / 2;
|
I'm thinking that the variable n is probably the m7 number. Notably, there is no reference to this in the line which calculates the x
coordinate.
Any ideas?
|
Yes, N is the variable that represents the mode7 number (of the window)
Quote: Originally posted by dom cook |
My best guess is that there's a variable out there called im7[n].an and subsituting it for vga_an in the alledged
offending line might just help solve the problem. This would account for the width of the region, to account for its start position we might try
im7[n].x
(we can already see that there is an im7[n].y)
My suggested correction would be this:
anchura = im7[n].x + im7[n].an/2 + (factor * distmax) / (max * 16);
[Edited on 11-5-2019 by dom cook] |
The im7 structure is an internal structure that stores data when a request is made to create mode7 using the START_MODE7 function.
X y Y represent the coordinates where it starts on the screen (physical resolution chosen for the game) of the mode7 window.
AN y AL represent the widh y the height of the mode7 window, these 2 variables are updated based on what you pass in the "region" parameter of the
START_MODE7 function, if you pass 0, they represent the width and height of the resolution (vga_an y vga_al), otherwise the width and the height of
the region (for example we pass a region 1 previously defined with DEFINE_REGION of 300x300).
Based on what you have indicated, the modification of the code could be correct, please publish the example so as to be able to prove the result.
|
|
Pages:
1
2 |