mirror of
https://git.code.sf.net/p/fuse-emulator/fuse
synced 2026-01-27 01:41:34 +03:00
121 lines
4.5 KiB
Plaintext
121 lines
4.5 KiB
Plaintext
Some brief instructions on adding another user interface to Fuse
|
|
================================================================
|
|
|
|
In order to add a new user interface (UI) to Fuse, you need to
|
|
implement:
|
|
|
|
* the functions listed in ui/ui.h
|
|
* the functions listed in ui/uidisplay.h
|
|
* some form of keyboard handling.
|
|
|
|
In general, all functions returning `int' should return zero on
|
|
success and non-zero on error unless otherwise specified.
|
|
|
|
As of Fuse 0.4.1, the specific code for each user interface sits in
|
|
its own directory under the ui/ directory.
|
|
|
|
ui.h
|
|
----
|
|
|
|
* int ui_init( int *argc, char ***argv )
|
|
|
|
Initialise all of the UI-specific bits except the display (keyboard, etc).
|
|
`argc' and `argv' are pointers to `argc' and `argv' as supplied to
|
|
`main()'.
|
|
|
|
* int ui_event( void )
|
|
|
|
`ui_event()' is called at the start of every emulated Spectrum frame,
|
|
and is the opportunity for the UI actions to happen. Some of the
|
|
current UIs, for example the GTK+ UI use this to do most of their
|
|
processing such as reading the keyboard and the like, whilst others,
|
|
for example the SVGAlib UI do much less here.
|
|
|
|
* int ui_verror( ui_error_level severity, const char *format, va_list ap )
|
|
|
|
This will be called whenever the emulator wishes to output an error
|
|
message of some form to the user; `severity' specifies how severe the
|
|
error is - possible values are in "ui/ui.h". Typical actions will
|
|
include writing the message to stderr and/or some form of dialog box
|
|
for the user to read.
|
|
|
|
* int ui_end( void )
|
|
|
|
`ui_end()' is called on emulator shutdown and should undo all the
|
|
setup done in `ui_init()'.
|
|
|
|
uidisplay.h
|
|
-----------
|
|
|
|
* int uidisplay_init( int width, int height )
|
|
|
|
Initialise all of the display-specific bits for a display of (preferred)
|
|
size `width' x `height' pixels; note that `width' and `height' refer
|
|
to the entire canvas on which the screen and emulated border is to be
|
|
drawn, not just the Spectrum's screen. This will be called each time
|
|
a machine is selected by the user to set the appropriate canvas
|
|
(typically 320x240 for Sinclair/Amstrad models, 640x480 for Timex
|
|
models to allow for hires modes).
|
|
|
|
* void uidisplay_area( int x, int y, int w, int h )
|
|
|
|
This should copy the area of size `w' x `h' at pixel ( `x', `y' ) from
|
|
the buffered copy of the Spectrum's screen (display.c:display_image)
|
|
to the real display. Note that pixel ( 0, 0 ) is the top-left pixel of
|
|
the emulated border, not that of the actual screen.
|
|
|
|
* void uidisplay_frame_end( void )
|
|
|
|
This is called at the end of every spectrum frame, giving the ui a
|
|
chance to flush all the drawing done over the course of the frame.
|
|
|
|
* int uidisplay_hotswap_gfx_mode( void )
|
|
|
|
This is called when the user has changed the scaler in use by the
|
|
emulator. The ui should change the window to a multiple of the
|
|
size set in uidisplay_init as required by the requested scaler.
|
|
A ui does not have to support all or any of the scalers.
|
|
|
|
* void uidisplay_end( void )
|
|
|
|
Just undo whatever was done by `uidisplay_init()'.
|
|
|
|
* void uidisplay_init_scalers( void );
|
|
|
|
This function should set the scalers supported for the particular
|
|
machine and ui in question. For example the half size scaler only
|
|
makes sense for Timex machines (as it drops even scanlines), and
|
|
you may only want to enable it when a Timex machine has been
|
|
enabled.
|
|
Alternatively, if your emulator has a fixed display mode (say
|
|
320x240), then you may want to only enable the scalers that will
|
|
generate a 320x240 screen (i.e. Normal1x for Sinclair/Amstrad
|
|
machines, and Half for Timex models).
|
|
|
|
Keyboard handling
|
|
-----------------
|
|
|
|
There are two different sorts of keys which the UI has to handle:
|
|
those which correspond to Spectrum keys, and those which control Fuse
|
|
in some way.
|
|
|
|
There are two functions to handle Spectrum-related keys (from `keyboard.h'):
|
|
|
|
* void keyboard_press ( keyboard_key_name key )
|
|
* void keyboard_release( keyboard_key_name key )
|
|
|
|
`keyboard_key_name' is an enum defined in `keyboard.h' which lists all
|
|
the Spectrum keys; calling these functions will cause the emulated
|
|
machine to believe that the corresponding Spectrum key has been
|
|
pressed or released.
|
|
|
|
If you're using widget code in your user interface, note that this
|
|
contains its own keyboard handling code, so you should ignore any
|
|
non-Spectrum keys if `widget_active' is true.
|
|
|
|
There is a general keyboard to Spectrum keys mapping listed in
|
|
`keysyms.dat', which is used to generate `keysyms.c' by
|
|
`keysyms.pl'. If you can generate a mapping from whatever your UI's
|
|
keyboard routines return to the Xlib keysyms used in `keysyms.dat',
|
|
this is probably the easiest way to deal with the Spectrum-related keys.
|