VgaGames4 - tutorial

Tutorial 6 

screenshot.gif

Now we want to add a system-menu, where we can redefine the keys and set the audio-volume. The design shall be a simple but self-made one.


At first an overview about modifications in the file pingpong.c.

pingpong.c: Overview about modifications

/* global declarations */
[...]

/* main function */
int main(int argc, char **argv) {
  /* variable declaration */
  [...]

  /* initializing */
  [...]      /* opening, collision functions and tag, loading audio files */
  [CODEBOX]  /* set keys */
  [...]      /* create object-instances */
  [...]      /* show help, start background music */

  /* game loop */
  [CODEBOX]  /* receive input-events and check the local key-strokes */
  [...]      /* call f_run() of all object-instances */
  [...]      /* clear window, draw background, call f_draw() of all object-instances */
  [...]      /* flush and wait */

  /* end game */
  [...]      /* destroy and exit */
}

In the file pingpong.h we add the key for showing the system-menu into the private structure of the game.

pingpong.h

#ifndef PINGPONG_H_
#define PINGPONG_H_

#include <vgagames4.h>

/* include export-functions to create new object-instances */
#include "objnew.h"

/* private structure of the game */
struct s_game {
  int winw, winh;  /* window's width and height */
  unsigned int coll_tag;  /* collision-tag */

  struct {  /* keys */
    int k_quit_lalt;  /* part of quit: Left-ALT */
    int k_quit_q;     /* part of quit: Q */
    int k_sysmenu;    /* system-menu */
    int k_pause;      /* pause */
    int k_up;         /* move up */
    int k_down;       /* move down */
  } kref;
};

#endif /* PINGPONG_H_ */

In the file pingpong.c when setting the keys, we add the key for the system-menu.

[To Position]
pingpong.c: set keys

/* set keys */

/* quit with ALT+Q, not changeable */
if ((sgame.kref.k_quit_lalt = vg4->input->key_insert("Quit-LALT", VG_FALSE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(sgame.kref.k_quit_lalt, VG_INPUT_KBDCODE_LALT);
if ((sgame.kref.k_quit_q = vg4->input->key_insert("Quit-Q", VG_FALSE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(sgame.kref.k_quit_q, VG_INPUT_KBDCODE_Q);

/* system-menu with ESC, not changeable */
if ((sgame.kref.k_sysmenu = vg4->input->key_insert("System-menu", VG_FALSE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(sgame.kref.k_sysmenu, VG_INPUT_KBDCODE_ESCAPE);

/* pause with P, changeable */
if ((sgame.kref.k_pause = vg4->input->key_insert("Pause", VG_TRUE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(sgame.kref.k_pause, VG_INPUT_KBDCODE_P);

/* move-up with cursor-key UP, changeable */
if ((sgame.kref.k_up = vg4->input->key_insert("Move up", VG_TRUE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(sgame.kref.k_up, VG_INPUT_KBDCODE_UCURS);
vg4->input->key_setgc(sgame.kref.k_up, 0, VG_INPUT_GCAXIS_RIGHTY_UP);

/* move-down with cursor-key DOWN, changeable */
if ((sgame.kref.k_down = vg4->input->key_insert("Move down", VG_TRUE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(sgame.kref.k_down, VG_INPUT_KBDCODE_DCURS);
vg4->input->key_setgc(sgame.kref.k_down, 0, VG_INPUT_GCAXIS_RIGHTY_DOWN);

When checking the local key-strokes, we add the check for the system-menu.

[To Position]
pingpong.c: entering game-loop: receive input-events and check the local key-strokes

/* game loop */
for (;;) {
  /* retrieve input-events */
  if (!vg4->input->update(VG_TRUE)) { goto endgame; }

  /* quit? */
  if (vg4->input->key_newpressed(sgame.kref.k_quit_q) && vg4->input->key_pressed(sgame.kref.k_quit_lalt)) { goto endgame; }

  /* pause? */
  if (vg4->input->key_newpressed(sgame.kref.k_pause)) {
    if (!vg4->misc->pause()) { goto endgame; }
  }

  /* system-menu? */
  if (vg4->input->key_newpressed(sgame.kref.k_sysmenu)) {
    struct VG_Hash *hvar = vg4->hash->create();
    vg4->nw->pause();  /* send pause-request to suspend the game */
    vg4->hash->setstr(hvar, "top:title", "System-menu");
    vg4->hash->setstr(hvar, "volume:top:title", "Set audio volumes");
    vg4->hash->setstr(hvar, "keydef:top:title", "Key Redefinition");
    vg4->hash->setstr(hvar, "keydef:press:title", "Press key");
    vg4->audio->suspend(VG_TRUE);
    if (!vg4->dialog->sysmenu("files/canvas", NULL, hvar, &sgame, NULL, NULL, NULL)) { goto endgame; }
    vg4->audio->suspend(VG_FALSE);
    vg4->hash->destroy(hvar);
  }

We put our own canvas-files for the system-menu and their images into the path files/canvas/. There are below - sysmenu/ the canvas for the system-menu - keydef/ the sub-canvasses for redefining the keys - volume/ the sub-canvas for setting the audio-volume

sysmenu/sysmenu.top.cvas: canvas for the system-menu

# we don't use an image as background, but draw it ourself: a blue box with a red frame
[MAIN]
%{txt[
  # red frame
  boxwidth=250
  boxheight=150
  bgcolor=0xb10000
  orientation=center
  v-orientation=center
 ]: %{txt[
  # blue box
  boxwidth=230
  boxheight=130
  bgcolor=0x000088
  utag-title=10+210,8+12
  utag-bt-volume=20+40,50+40
  utag-bt-keydef-kbd=95+40,50+40
  utag-bt-keydef-gc=170+40,50+40
  utag-done=90+50,105+20
 ]:%}
%}

[VAR-DEFAULT]
var.title: System-Menu

[MOUSE]
disable: 0

[FONT]
sys:low

# the title of the canvas
[CV-TEXT]
name: title
position-itag: title
default-text: %{var: title%}
text.orientation: center+left
text.v-orientation: center
text.fgcolor: 0xffff00
text.nowrap: 1

# the button for the volume
[CV-BUTTON]
name: bt-volume
position-itag: bt-volume
img-dfl: img:sysm-button-volume-dfl.bmp
img-act: img:sysm-button-volume-act.bmp

# the button for redefining the keyboard-keys
[CV-BUTTON]
name: bt-keydef-kbd
position-itag: bt-keydef-kbd
img-dfl: img:sysm-button-kd_kbd-dfl.bmp
img-act: img:sysm-button-kd_kbd-act.bmp

# the button for redefining the gamecontroller-keys
[CV-BUTTON]
name: bt-keydef-gc
position-itag: bt-keydef-gc
img-dfl: img:sysm-button-kd_gc-dfl.bmp
img-act: img:sysm-button-kd_gc-act.bmp

# the OK-button
[CV-BUTTON]
name: done
position-itag: done
img-dfl: img:../button-done-dfl.bmp
img-act: img:../button-done-act.bmp

sysmenu/keydef.top.cvas: sub-canvasses for redefining the keys: top-canvas

# we don't use an image as background, but draw it ourself: a blue box with a red frame
[MAIN]
%{txt[
  # red frame
  boxwidth=250
  boxheight=150
  bgcolor=0xb10000
  orientation=center
  v-orientation=center
 ]: %{txt[
  # blue box
  boxwidth=230
  boxheight=130
  bgcolor=0x000088
  utag-title=10+210,8+12
  utag-device=10+210,24+12
  utag-keylist=10+210,40+60
  utag-done=90+50,105+20
 ]:%}
%}

[VAR-DEFAULT]
var.title:
var.device:

[MOUSE]
disable: 0

[FONT]
sys:low

# the title of the canvas
[CV-TEXT]
name: title
position-itag: title
default-text: %{var: title%}
text.orientation: center+left
text.v-orientation: center
text.fgcolor: 0xffff00
text.nowrap: 1

# the name of the device (e.g. name of gamecontroller)
[CV-TEXT]
name: device
position-itag: device
default-text: %{var: device%}
text.orientation: center+left
text.v-orientation: center
text.fgcolor: 0xffffff
text.nowrap: 1

# a list with the defined keys
[CV-LIST]
name: keylist
position-itag: keylist
spacing: 2+
fgcolor-dfl: 0xeeee00
fgcolor-act: 0x003670
bgcolor-dfl: 0x003670
bgcolor-act: 0xeeee00
bgcolor: 0x003670

# the OK-button
[CV-BUTTON]
name: done
position-itag: done
img-dfl: img:../button-done-dfl.bmp
img-act: img:../button-done-act.bmp

sysmenu/keydef.gclist.cvas: sub-canvasses for redefining the keys: canvas for showing gamecontrollers

# we don't use an image as background, but draw it ourself: a blue box with a red frame
[MAIN]
%{txt[
  # red frame
  boxwidth=250
  boxheight=150
  bgcolor=0xb10000
  orientation=center
  v-orientation=center
 ]: %{txt[
  # blue box
  boxwidth=230
  boxheight=130
  bgcolor=0x000088
  utag-gclist=10+210,10+110
 ]:%}
%}

[MOUSE]
disable: 0

[FONT]
sys:low

[ACTIVATED]
gclist

# list with found gamecontrollers
[CV-LIST]
name: gclist
position-itag: gclist
spacing: 2+
fgcolor-dfl: 0xeeee00
fgcolor-act: 0x003670
bgcolor-dfl: 0x003670
bgcolor-act: 0xeeee00
bgcolor: 0x003670

sysmenu/keydef.press.cvas: sub-canvasses for redefining the keys: canvas for pressing a new key

# we don't use an image as background, but draw it ourself: a blue box with a red frame
[MAIN]
%{txt[
  # red frame
  boxwidth=200
  boxheight=120
  bgcolor=0xb10000
  orientation=center
  v-orientation=center
 ]: %{txt[
  # blue box
  boxwidth=180
  boxheight=100
  bgcolor=0x000088
  utag-title=10+160,8+12
  utag-keyname=10+160,36+12
  utag-keypress=15+150,70+14
 ]:%}
%}

[VAR-DEFAULT]
var.title: Redefine key
var.keyname: Unknown

[MOUSE]
disable: 1

[FONT]
sys:low

[ACTIVATED]
keypress

# the title of the canvas
[CV-TEXT]
name: title
position-itag: title
default-text: %{var: title%}
text.orientation: center+left
text.v-orientation: center
text.fgcolor: 0xffff00
text.nowrap: 1

# the name of the key
[CV-TEXT]
name: keyname
position-itag: keyname
default-text: %{var: keyname%}
text.orientation: center
text.v-orientation: center
text.fgcolor: 0xffffff
text.nowrap: 0

# for pressing a new key
[CV-UNIQKEY]
name: keypress
position-itag: keypress
fgcolor: 0x00cccc

sysmenu/volume.top.cvas: sub-canvas for setting the audio-volume

# we don't use an image as background, but draw it ourself: a blue box with a red frame
[MAIN]
%{txt[
  # red frame
  boxwidth=200
  boxheight=150
  bgcolor=0xb10000
  orientation=center
  v-orientation=center
 ]: %{txt[
  # blue box
  boxwidth=180
  boxheight=130
  bgcolor=0x000088
  utag-title=10+160,8+12
  utag-mute=18+20,25+16
  utag-bartext-main=18+70,50+12
  utag-bar-main=95+50,53+6
  utag-bartext-sound=18+70,70+12
  utag-bar-sound=95+50,73+6
  utag-bartext-music=18+70,90+12
  utag-bar-music=95+50,93+6
  utag-apply=65+50,105+20
 ]:%}
%}

[VAR-DEFAULT]
var.title: Set volume

[MOUSE]
disable: 0

[FONT]
sys:low

# the title of the canvas
[CV-TEXT]
name: title
position-itag: title
default-text: %{var: title%}
text.orientation: center+left
text.v-orientation: center
text.fgcolor: 0xffff00
text.nowrap: 1

# a switch for setting volume to mute and unmute
[CV-SWITCH]
name: mute
position-itag: mute
img-on-dfl: img:vol-mute-dfl.bmp
img-on-act: img:vol-mute-act.bmp
img-off-dfl: img:vol-unmute-dfl.bmp
img-off-act: img:vol-unmute-act.bmp

# name of main-volume
[CV-TEXT]
name: bartext-main
position-itag: bartext-main
default-text: Main
text.orientation: left
text.v-orientation: center
text.fgcolor: 0xffff00
text.nowrap: 1

# setting main-volume
[CV-BAR]
name: bar-main
position-itag: bar-main

# name of sound-volume
[CV-TEXT]
name: bartext-sound
position-itag: bartext-sound
default-text: Sound
text.orientation: left
text.v-orientation: center
text.fgcolor: 0xffff00
text.nowrap: 1

# setting sound-volume
[CV-BAR]
name: bar-sound
position-itag: bar-sound

# name of music-volume
[CV-TEXT]
name: bartext-music
position-itag: bartext-music
default-text: Music
text.orientation: left
text.v-orientation: center
text.fgcolor: 0xffff00
text.nowrap: 1

# setting sound-volume
[CV-BAR]
name: bar-music
position-itag: bar-music

# the OK-button
[CV-BUTTON]
name: apply
position-itag: apply
img-dfl: img:../button-done-dfl.bmp
img-act: img:../button-done-act.bmp



<<Previous Download Next>>