First steps into Z88DK...and many more to come!

Discuss game and other programming topics not specifically covered in another forum

Moderator: Programming Moderators

SamusDrake
Posts: 250
Joined: Mon Jun 26, 2017 10:11 pm
Contact:

Re: First steps into Z88DK...and many more to come!

Post by SamusDrake » Thu Feb 22, 2018 11:13 pm

A companion Java app to the last code example, this "Sprite editor" only does an 8*8 pixel tile, converts it to binary and then finally compresses each row into a single byte value...


Image


I made this in Swing( a Java api ) and it was great fun. Not sure what is coming next, but stay tuned all the same...

SamusDrake
Posts: 250
Joined: Mon Jun 26, 2017 10:11 pm
Contact:

Re: First steps into Z88DK...and many more to come!

Post by SamusDrake » Sun Mar 04, 2018 8:07 pm

Heres a bit of fixed point programming...

Code: Select all

/*********************************************************
 * 
 *	"fixedPoint.c" by S.A Ray (SamusDrake)				 
 *							 
 * This program explores fixed point calculations.
 * Floating point operations are very expensive
 * for older cpus - especially those without FPUs, so
 * the idea is to first convert a float value into a 
 * whole number or long-integer. Then we perform calucations
 * using that long-integer. 
 *
 * The reason for using fixed point maths is speed.
 * Vector and full 3D games on home computers and game
 * consoles are good examples.
 *
 * There are two cons to using fixpoint maths. The first
 * is the extra code required and the second is loss of 
 * precission.  For a machine like the spectrum, the trade
 * off is worth it for the extra speed.
 *
 *********************************************************
 *
 * This program was made using Andre Lamothe's book
 * "Tricks of the Windows Gaming programming Gurus" as
 * reference.
 * 
 * I managed to get the idea of fixed point maths but
 * implementing it on the Spectrum hasn't been entirely 
 * successful. The big issue is dealing with a negative 
 * fixpoint value, and a correction needs to be performed.
 *
 *********************************************************
 *
 * NOTE: NEGATIVE CORRECTION
 *
 * If the fixed point is holding a negative value, say
 * -4.03, then the integral part will be -5, and the 
 * decimal part something like 247. That is not correct.
 * The integral part is easily solved by adding a postive 1.
 * The decimal requires further explaination...
 * 
 * The decimal part - in this program - is stored in a single 
 * byte, with a maximum value of 255. So 0.5 will be stored as
 * integral: 0, decimal: 128. Unfortunately, the decimal part
 * is kinda done "backwards" when stored negatively, and so, we
 * merely subtract the decimal part from the maximum value 255.
 * Doing this for -4.03, the decimal part should be about the value
 * of 8-10, or a very low value...
 *
 * 0-to-255 can be thought of as 0.0-to-1.0
 *
 * In a nutshell, do a check for a negative value and if it 
 * is then perform the correction. The two macros to correct the
 * integral and decimal parts of a fixpoint are, respectivley...
 *
 * CONVERT_NEG_INT_PART(n)
 * CONVERT_NEG_DEC_PART(n)
 *
 *********************************************************
 *
 * Compile with: zcc +zx -vn -lm -lndos -create-app fixedPoint.c
 *
 *********************************************************         
 *
 * Written using z88dk.
 *
 * As always, cheers to the community at the ZX Spectrum 
 * Next forum. ^_^
 *
 *********************************************************/ 

#include <stdio.h>

#define FP_SHIFT 8
#define FP_SCALE 256

// Conversion macros
#define INT_TO_FIXP(n)   ( n << FP_SHIFT )
#define FLOAT_TO_FIXP(n) ( (float)n * FP_SCALE )

// Extraction macros( obtain whole part and the decimal part )
#define EXTRACT_INT_PART(n) ( n >> FP_SHIFT )
#define EXTRACT_DEC_PART(n) ( n & 0x000000FF )

// Multiplication and divide macros
#define FIXP_MULTIPLY(a,b) ( (a*b) >> FP_SHIFT )
#define FIXP_DIVIDE(a,b)   ( (a << FP_SHIFT) / b )	

// Macros to correct negative fixpoints.
#define CONVERT_NEG_INT_PART(n) ( n + 1 )
#define CONVERT_NEG_DEC_PART(n) ( FP_SCALE - n )

// An integer for Z88DK is 2 bytes, but 
// using a long gives us 4 bytes to work with...
typedef long FIXPOINT;


/**
 * Program entry point
 */
main()
{
	float 	value1 		= 10.5;
	float 	value2 		= -2.6;
	float 	divisionResult 	= 0;
	long 	interest 	= 1;
	int  	correctIntegral;
	int 	correctDecimal;

	FIXPOINT n1, n2, n3;

	clg();

	n1 = FLOAT_TO_FIXP( value1 );
	n2 = FLOAT_TO_FIXP( value2 );

	// It is important to store the result of a floating point
	// Calculation into a variable. I assume this is due to 
        // Z88DK providing floating point support in software only.
	// Of course, the Spectrum never had hardware support in the
	// first place... 
	n3 = FIXP_DIVIDE( n1, n2 );

	divisionResult = value1 / value2;

	printf( "GIVEN VALUES AND DIVISION RESULT - BEFORE FIX-POINT\n" );
	printf( "***************************************************\n");	
	printf( "Value 1: %f", value1 );
	printf( "\nValue 2: %f", value2 );
	printf( "\nResult : %f", divisionResult );

	// Do note that long types will require the specifier %ld, and not just %d.
	printf( "\n\n\nINCORRECT NEGATIVE RESULT\n" );
	printf( "*************************\n");
	printf( "INTEGRAL: %ld", EXTRACT_INT_PART(n3) );
	printf( "\nDECIMAL : %ld",  EXTRACT_DEC_PART(n3) );

	printf( "\n\n\nCORRECTED NEGATIVE RESULT\n" );
	printf( "*************************\n" );
	correctIntegral = CONVERT_NEG_INT_PART( EXTRACT_INT_PART(n3) );
	correctDecimal  = CONVERT_NEG_DEC_PART( EXTRACT_DEC_PART(n3) );
	printf("INTEGRAL: %d",  correctIntegral );
	printf("\nDECIMAL : %d", correctDecimal );
}


SamusDrake
Posts: 250
Joined: Mon Jun 26, 2017 10:11 pm
Contact:

Re: First steps into Z88DK...and many more to come!

Post by SamusDrake » Sun Mar 04, 2018 8:09 pm

I'm doing a bit more on the sprite editor, where multiple sprites can be selected and edited. I think I'm at the point where I shall have to look into how the spectrum saves and loads files...

SamusDrake
Posts: 250
Joined: Mon Jun 26, 2017 10:11 pm
Contact:

Re: First steps into Z88DK...and many more to come!

Post by SamusDrake » Thu Apr 26, 2018 8:58 pm

Thought it was high time I learned sound programming and this is the first effort. I used a DirectMusic utility years ago and enjoyed the process but sadly wasnt any good at it...

Code: Select all

/*********************************************************
 * 
 * "music.c" by S.A Ray (SamusDrake)				 
 *							 
 * This program deals with music, of all things using the
 * Speccys 1-bit beeper. Yuzo Koshiro eat your heart
 * out!
 *
 * Just kidding as it merely plays a few notes and I dont
 * think I have them right neither. Music is in the realm 
 * of sorcery as far as I am concerned and so what I have 
 * learned so far is mostly from a  wonderful site called 
 * "Bytes: Chuntey", which has hosted tutorials by a rather 
 * clever gentleman named Jonathan Cauldwell.   
 *
 ********************************************************* 
 *
 * Compile with: zcc +zx -lm -lndos -create-app music.c
 *
 *********************************************************         
 *
 * Written using z88dk.
 *
 * Thank you to the community at the ZX Spectrum 
 * Next forum, and the Speccy community at large.
 * 
 * Many thanks to "Bytes: Chuntey" and of course
 * Jonathan Cauldwell.
 *
 *********************************************************/ 

#include <stdio.h>
#include <sound.h>

int main()
{
	clg();
	printf("Its a tuuuuuuuuuuuuuune!");

	// bit_beep(duration, pitch)
	bit_beep(78,1642); // C
	bit_beep(83,1548); // C-Sharp
	bit_beep(88,1460); // D
	bit_beep(93,1376); // D-Sharp
	bit_beep(99,1297); // E
	bit_beep(105,1223); // F
	bit_beep(111,1152); // F-Sharp
	bit_beep(118,1086); // G
	bit_beep(125,1023); // G-Sharp
	bit_beep(132,964); // A
	bit_beep(139,908); // A-Sharp
	bit_beep(148,856); // B
}
...not sure where to go from here as I dont really have a grasp as to how to store a whole tune in a speccy nor even how to make a tune in the first place. Surprisingly there are far fewer sound programming tutorials than visual ones, but only having to worry about a single channel does make things easier to cope with.

SamusDrake
Posts: 250
Joined: Mon Jun 26, 2017 10:11 pm
Contact:

Re: First steps into Z88DK...and many more to come!

Post by SamusDrake » Thu Apr 26, 2018 9:14 pm

In other news I've been trying to set up Z88dk to work with CodeBlocks on my Windows 10 machine. My recent attempt has produced the following issue...

Code: Select all


-------------- Build: default in zeedk (compiler: Z88DK Compiler)---------------

zcc.exe -Wall -O2 zcc +zx -vn -clib=sdcc_iy -startup=31 main.c -o main -create-app  -c "D:\ZXSpectrum projects\DevProjects\zeedk\main.c" -o out\main.o
A config file must be specified with +file as the first argument
zcc - Frontend for the z88dk Cross-C Compiler - v9940-c8325f4-20171001
Usage: zcc.exe +[target] {options} {files}
Process terminated with status 1 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))

...for which I'm scratching my head as to which setup is at fault - my installation of Z88DK or adding Z88DK to Codeblocks. Maybe its the way I have setup the project?

Alcoholics Anonymous
Posts: 508
Joined: Mon May 29, 2017 7:00 pm

Re: First steps into Z88DK...and many more to come!

Post by Alcoholics Anonymous » Fri Apr 27, 2018 5:06 am

...for which I'm scratching my head as to which setup is at fault - my installation of Z88DK or adding Z88DK to Codeblocks. Maybe its the way I have setup the project?
The compile line is messed up so the problem must be in codeblocks.

zcc.exe -Wall -O2 zcc +zx -vn -clib=sdcc_iy -startup=31 main.c -o main -create-app -c "D:\ZXSpectrum projects\DevProjects\zeedk\main.c" -o out\main.o

(and "+zx" would be "+zxn" if targetting the zx next rather than spectrum)

So should be:

zcc +zx -vn -clib=sdcc_iy -startup=31 -c "D:\ZXSpectrum projects\DevProjects\zeedk\main.c"

Your compile is a little bit different from the others seen on the forum because you're not making a binary but rather an object file because of "-c". I took out the "-o main.o" part which you may want to put back in. zcc will form the name "main.o" on its own and will place the object file in the same directory as the source file so if you want specific control over that you may want to restore "-o ...".

"-create-app" is not needed (and will be ignored) because you're not making a final executable. "-create-app" causes zcc to invoke another program in z88dk called "appmake" that will take the output binaries generated and make them into a suitable form for the target like sna, tap, etc.

"-Wall" is not an option understood by zcc.

"-O2" you have to be careful with because it means different things for sccz80 and zsdcc. For sccz80 it's selecting a peephole optimization level with "-O2" meaning high (this is the default) and "-O3" meaning small code. For zsdcc it's selecting post-processing with "-O2" the default and no real reason to change it from that. The "-O2" does a translation from zsdcc's non-standard mnemonic output to more standard zilog form, then it changes how zsdcc calls its compiler primitives from standard c linkage to smaller callee linkage and finally it applies a few bugfixes. zsdcc uses "-SO" to select peephole optimization level with "-SO2" being the default and "-SO3" being more aggressive.

There is an issue that catches many people when they compile to object files and then link them all together and that's in how pragmas are collected for the final linking step. To avoid those issues, always use a separate pragma file to collect pragmas in one spot rather than embedding them in the c source. If you want to know details you can ask. If you're not using any pragmas yet then you don't have to worry about it but any programming project that is not just trying things out will have pragmas involved to control aspects of the compile.

Alcoholics Anonymous
Posts: 508
Joined: Mon May 29, 2017 7:00 pm

Re: First steps into Z88DK...and many more to come!

Post by Alcoholics Anonymous » Fri Apr 27, 2018 5:21 am

...not sure where to go from here as I dont really have a grasp as to how to store a whole tune in a speccy nor even how to make a tune in the first place. Surprisingly there are far fewer sound programming tutorials than visual ones, but only having to worry about a single channel does make things easier to cope with.
I can see you're using the classic library there but the newlib has some more 1-bit sound related functions. Among them are:

bit_beepfx() which is shiru's 1-bit sound effects player. This comes with about 50 different sound effects.
Example program is here: https://github.com/z88dk/z88dk/blob/mas ... S/beepfx.c
You can compile that for the +zx or +zxn targets to hear the built in sound effects. Shiru has an effects editor available for windows that you can use to make your own 1-bit sound effects.

bit_play_tritone() which can play tritone music composed using beepola.
Example program is here: https://github.com/z88dk/z88dk/tree/mas ... mo_tritone
Click on "demo.tap" and then the download button to get the tap file for a spectrum emulator or the next.

bit_play() which will play notes stored in a string.
See https://github.com/z88dk/z88dk/blob/mas ... ay.asm#L13

... and several other more primitive functions.

The header file is "sound/bit.h" (see https://github.com/z88dk/z88dk/blob/mas ... ound/bit.h ). Interrupts should be disabled while these things run because 1-bit music is controlled by cpu timing so any interrupt will mess with the audio. Using the *_di variant of functions is an easy way to do that. These functions will disable interrupts, do their thing, then restore interrupt state to whatever it was before the call. As mentioned these are cpu-timed which means the notes and note duration depend on cpu speed. The cpu speed is set at library build time and can be changed away from the default 3.5MHz if you will be calling these functions while the Next is running at a faster speed.

Regarding a couple of previous posts on the topics of reading keyboard and drawing lines, there is some discussion of that in this tutorial:
https://github.com/z88dk/z88dk/blob/mas ... Devices.md and https://github.com/z88dk/z88dk/blob/mas ... raphics.md .

For reading the keyboard, joysticks or mouse the input library is preferred. The functions there read the hardware directly and have an easy to use interface. The line drawing example is using a bresenham implementation found on the internet. It's fast but it is not the fastest way to draw a line. The main reason for that is that it deals in x,y coordinates and must compute screen addresses for every point plotted. For speed, it should be dealing in screen addresses directly and modifying those to move left,right,up,down as necessary. The new pixelad instruction might change that but that is not implemented yet in the z88dk libraries. Although you can get speedy results in c for a draw line, this is something that should be implemented in asm because it's going to be a performance bottleneck.

There is also a sophisticated software sprite engine in z88dk called sp1. An example can be found here: https://github.com/z88dk/z88dk/tree/mas ... _sp1/demo1 . Click on "demo.tap" and then download to run on an emulator. Press any key to reset the sprites. You can try increasing the emulation speed to 14MHz to see how things would behave on the zx next; it's planned to port this library to all the zx next display modes so that it will be easy to mix hardware and software sprites from different modes.

SamusDrake
Posts: 250
Joined: Mon Jun 26, 2017 10:11 pm
Contact:

Re: First steps into Z88DK...and many more to come!

Post by SamusDrake » Fri Apr 27, 2018 7:47 am

Alvin, thats given me a lot to go on! Thank you for taking the time out to help me on those issues.

SamusDrake
Posts: 250
Joined: Mon Jun 26, 2017 10:11 pm
Contact:

Re: First steps into Z88DK...and many more to come!

Post by SamusDrake » Sat Apr 28, 2018 8:58 am

Okay, I spent yesterday with Codeblocks trying to figure out where I have gone wrong, and came up with the following possibilities...

1) I havent installed Z88DK correctly on Windows 10(works a charm in Linux though).
2) I've incorrectly setup the environment variables.
3) I've incorrectly setup the Z88DK compiler in CodeBlocks.
4) My project/build settings are simply wrong.

...what I have managed to achieve was to go into Project/target options and set the option to make a custom make file, which I then provided in the project folder. Its contents are...

Code: Select all

zcc +zx -vn -clib=sdcc_iy -startup=31 -c "D:\ZXSpectrum projects\DevProjects\zeedk\main.c"
...which seem to be correct. Mucking around in the "Toolchain Executables" in the Global Compiler settings, I have the current program files linked...

Code: Select all

C Compiler:  zcc.exe
C++ Compiler: zcc.exe
Linker for dynamic Libs: z88dk-lib.exe
Linker for static libs: z88dk-lib.exe
Debugger: GDB/CDB debugger: default
Resouce compiler: windres.exe
Make program: appmake.exe
...and I think this is where I am screwing up. When building the project I now get the following build log...

Code: Select all


-------------- Build: default in zeedk (compiler: Z88DK Compiler)---------------

Checking if target is up-to-date: appmake.exe -q -f Makefile default
Running command: appmake.exe -f Makefile default
appmake [+target] [options]
The z88dk application generator
This program is used to produce files which are suitable for use in
emulators or on the real hardware. Supported targets are:
+abc80        (abccas  ) - (C) 2000 Stefano Bodrato, (C) 2008 Robert Juhasz 
+ace          (acetap  ) - (C) 2001 Stefano Bodrato
+aquarius     (bin2caq ) - (C) 2001 Stefano Bodrato
+c128         (bin3000 ) - (C) 2001 Stefano Bodrato
+cpc          (bin2cpc ) - (C) 2003 Dominic Morris, (C) 1997 Pierre Thevenet
+enterprise   (bin2ep  ) - (C) 2011 Stefano Bodrato
+gal          (bin2gtp ) - (C) 2007,2008 Tomaz Solc & Stefano Bodrato
+hex          (bin2hex ) - (C) 2001 Dominic Morris & Jeff Brown
+newext       (newext  ) - (C) 2014 Stefano Bodrato
+inject       (inject  ) - (C) 2014 Dominic Morris
+extract      (extract ) - (C) 2015 Alvin Albrecht
+kc           (kcc     ) - (C) 2016 Stefano Bodrato
+lynx         (lynxtap ) - (C) 2014 Stefano Bodrato
+m5           (bin2m5  ) - (C) 2010 Stefano Bodrato
+mc           (mc1000  ) - (C) 2013 Stefano Bodrato
+msx          (bin2msx ) - (C) 2001 Stefano Bodrato
+mtx          (bin2mtx ) - (C) 2011 Stefano Bodrato
+mz           (bin2m12 ) - (C) 2000,2003 S. Bodrato, J.F.J. Laros, M. Nemecek
+nas          (bin2nas ) - (C) 2003 Stefano Bodrato
+nec          (hex2cas ) - (C) 2003,2007 Takahide Matsutsuka
+px           (px2rom  ) - (C) 2015 Stefano Bodrato
+p2000        (mc2cas  ) - (C) 2014 Stefano Bodrato
+c7420        (bin7420 ) - (C) 2015 Stefano Bodrato
+residos      (bin2pkg ) - (C) 2014 Dominic Morris
+rom          (rompad  ) - (C) 2014,2017 Stefano Bodrato & Alvin Albrecht
+glue         (gluebin ) - (C) 2017 Alvin Albrecht
+srr          (dgos    ) - (C) 2011, 2017 Stefano Bodrato
+sos          (sentinel) - (C) 2013 Stefano Bodrato
+newbrain     (bin2nwbn) - (C) 2007 Stefano Bodrato
+rex          (mkaddin ) - (C) 2001 Dominic Morris
+ti82         (bin2var ) - (C) 2000,2003 David Phillips et al
+ti83         (bin2var ) - (C) 2000,2003 David Phillips et al
+ti8x         (bin2var ) - (C) 2000,2003 David Phillips et al
+ti85         (bin2var ) - (C) 2000,2003 David Phillips et al
+ti86         (bin2var ) - (C) 2000,2003 David Phillips et al
+ti86s        (bin2var ) - (C) 2000,2003 David Phillips et al
+svi          (bin2svi ) - (C) 2001 Stefano Bodrato
+sms          (bin2sms ) - (C) 2007 Dominic Morris
+trs80        (bin2cmd ) - (C) 2008 Stefano Bodrato
+sc3000       (bin2sc  ) - (C) 2010 Stefano Bodrato
+vz           (vz2cas  ) - (C) 2010 Stefano Bodrato
+vg5k         (vg5k2k7 ) - (C) 2014 Stefano Bodrato
+z88          (appz88  ) - (C) 2000,2003 Dominic Morris & Dennis Groning
+x07          (x07cas  ) - (C) 2011 Stefano Bodrato
+z1013        (z1013   ) - (C) 2016 Stefano Bodrato
+z9001        (kctape  ) - (C) 2016 Stefano Bodrato
+z88shell     (shellmak) - (C) 2002,2003 Dominic Morris
+zxvgs        (appzxvgs) - (C) 2003 Yarek
+zx           (bin2tap ) - (C) 2000,2003,2017 Morris, Bodrato, Albrecht
+zxn          (zxnext  ) - (C) 2000,2003,2017 Morris, Bodrato, Albrecht
+zx81         (bin2p   ) - (C) 2000 Stefano Bodrato
For more usage information use +[target] with no options
Process terminated with status 1 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
...which makes me think I have the wrong programs connected to the toolchain. I've either missed a step or I've given the wrong things to Codeblocks to work with.
Last edited by SamusDrake on Sat Apr 28, 2018 9:37 am, edited 1 time in total.

SamusDrake
Posts: 250
Joined: Mon Jun 26, 2017 10:11 pm
Contact:

Re: First steps into Z88DK...and many more to come!

Post by SamusDrake » Sat Apr 28, 2018 9:36 am

In other news! My work on SGDK(Megadrive sdk) isnt going too bad but I'm having palette nightmares. Dealing in 16 color bitmaps is a headache, and I find my trusty copy of Tricks of the windows programming Gurus seeing action once again...

I registered with Sprites Mind but sadly they havent replied so I'm unable to ask questions there. Shame because it seems to have great community spirit, although I think the owner of the site is having trouble with hosting? Ah well.

Spent a little bit of time looking at the Master System again. Somehow its nice that Z88DK provides a small but powerful "api" for the SMS, when compared to SGDK which is quite a meaty sdk but the tutorials are sadly out of date, and the palette functions don't seem to work neither. For my situation the SMS is like a bridge between the Spectrum and Megadrive, and Z88DK seems to be more up to date.

Which brings me to the last thought of the day - how much hassle would it be to put a program onto a chip'n'pcb and pop it into a real Mastersystem! Or getting a suitable FPGA board - low cost of course - and setting it up as a Master System...hmmm.

Post Reply