summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/m_atom.c
blob: 654448abd2940aaf6e153fdcd074621769ae4e71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */

#include "m_pd.h"

#ifdef ROCKBOX
#include "plugin.h"
#include "../../pdbox.h"
#else /* ROCKBOX */
#include <stdio.h>
#include <string.h>
#endif /* ROCKBOX */

    /* convenience routines for checking and getting values of
    	atoms.  There's no "pointer" version since there's nothing
    	safe to return if there's an error. */

t_float atom_getfloat(t_atom *a)
{
    if (a->a_type == A_FLOAT) return (a->a_w.w_float);
    else return (0);
}

t_int atom_getint(t_atom *a)
{
    return (atom_getfloat(a));
}

t_symbol *atom_getsymbol(t_atom *a)  /* LATER think about this more carefully */
{
#ifndef ROCKBOX
    char buf[30];
#endif
    if (a->a_type == A_SYMBOL) return (a->a_w.w_symbol);
    else return (&s_float);
}

t_symbol *atom_gensym(t_atom *a)  /* this works  better for graph labels */
{
    char buf[30];
    if (a->a_type == A_SYMBOL) return (a->a_w.w_symbol);
    else if (a->a_type == A_FLOAT)
#ifdef ROCKBOX
        ftoan(a->a_w.w_float, buf, sizeof(buf)-1);
#else
    	sprintf(buf, "%g", a->a_w.w_float);
#endif
    else strcpy(buf, "???");
    return (gensym(buf));
}

t_float atom_getfloatarg(int which, int argc, t_atom *argv)
{
    if (argc <= which) return (0);
    argv += which;
    if (argv->a_type == A_FLOAT) return (argv->a_w.w_float);
    else return (0);
}

t_int atom_getintarg(int which, int argc, t_atom *argv)
{
    return (atom_getfloatarg(which, argc, argv));
}

t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv)
{
    if (argc <= which) return (&s_);
    argv += which;
    if (argv->a_type == A_SYMBOL) return (argv->a_w.w_symbol);
    else return (&s_);
}

/* convert an atom into a string, in the reverse sense of binbuf_text (q.v.)
* special attention is paid to symbols containing the special characters
* ';', ',', '$', and '\'; these are quoted with a preceding '\', except that
* the '$' only gets quoted at the beginning of the string.
*/

void atom_string(t_atom *a, char *buf, unsigned int bufsize)
{
    char tbuf[30];
    switch(a->a_type)
    {
    case A_SEMI: strcpy(buf, ";"); break;
    case A_COMMA: strcpy(buf, ","); break;
    case A_POINTER:
    	strcpy(buf, "(pointer)");
    	break;
    case A_FLOAT:
#ifdef ROCKBOX
        ftoan(a->a_w.w_float, tbuf, sizeof(tbuf)-1);
#else
    	sprintf(tbuf, "%g", a->a_w.w_float);
#endif
    	if (strlen(tbuf) < bufsize-1) strcpy(buf, tbuf);
    	else if (a->a_w.w_float < 0) strcpy(buf, "-");
    	else  strcat(buf, "+");
    	break;
    case A_SYMBOL:
    {
    	char *sp;
    	unsigned int len;
	int quote;
    	for (sp = a->a_w.w_symbol->s_name, len = 0, quote = 0; *sp; sp++, len++)
    	    if (*sp == ';' || *sp == ',' || *sp == '\\' || 
	    	(*sp == '$' && sp == a->a_w.w_symbol->s_name && sp[1] >= '0'
		    && sp[1] <= '9'))
    	    	quote = 1;
    	if (quote)
    	{
    	    char *bp = buf, *ep = buf + (bufsize-2);
    	    sp = a->a_w.w_symbol->s_name;
    	    while (bp < ep && *sp)
    	    {
    	    	if (*sp == ';' || *sp == ',' || *sp == '\\' ||
    	    	    (*sp == '$' && bp == buf && sp[1] >= '0' && sp[1] <= '9'))
    	    	    	*bp++ = '\\';
    	    	*bp++ = *sp++;
    	    }
    	    if (*sp) *bp++ = '*';
    	    *bp = 0;
    	    /* post("quote %s -> %s", a->a_w.w_symbol->s_name, buf); */
    	}
    	else
    	{
    	    if (len < bufsize-1) strcpy(buf, a->a_w.w_symbol->s_name);
    	    else
    	    {
    		strncpy(buf, a->a_w.w_symbol->s_name, bufsize - 2);
    		strcpy(buf + (bufsize - 2), "*");
    	    }
	}
    }
    	break;
    case A_DOLLAR:
    	snprintf(buf, bufsize, "$%d", a->a_w.w_index);
    	break;
    case A_DOLLSYM:
    	snprintf(buf, bufsize, "$%s", a->a_w.w_symbol->s_name);
    	break;
    default:
    	bug("atom_string");
    }
}

'>738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
/* Emacs style mode select   -*- C++ -*-
 *-----------------------------------------------------------------------------
 *
 *
 *  PrBoom a Doom port merged with LxDoom and LSDLDoom
 *  based on BOOM, a modified and improved DOOM engine
 *  Copyright (C) 1999 by
 *  id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
 *  Copyright (C) 1999-2000 by
 *  Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 *  02111-1307, USA.
 *
 * DESCRIPTION:  heads-up text and input code
 *
 *-----------------------------------------------------------------------------
 */

#include "doomdef.h"
#include "doomstat.h"
#include "v_video.h"
#include "m_swap.h"
#include "hu_lib.h"
#include "hu_stuff.h"
#include "r_main.h"
#include "r_draw.h"

#include "rockmacros.h"

// boolean : whether the screen is always erased
#define noterased viewwindowx

extern int  key_backspace;                                          // phares
extern int  key_enter;                                              // phares

//
// not used currently
// code to initialize HUlib would go here if needed
//
void HUlib_init(void)
{
}

////////////////////////////////////////////////////////
//
// Basic text line widget
//
////////////////////////////////////////////////////////

//
// HUlib_clearTextLine()
//
// Blank the internal text line in a hu_textline_t widget
//
// Passed a hu_textline_t, returns nothing
//
void HUlib_clearTextLine(hu_textline_t* t)
{
   t->linelen =         // killough 1/23 98: support multiple lines
      t->len = 0;
   t->l[0] = 0;
   t->needsupdate = true;
}

//
// HUlib_initTextLine()
//
// Initialize a hu_textline_t widget. Set the position, font, start char
// of the font, and color range to be used.
//
// Passed a hu_textline_t, and the values used to initialize
// Returns nothing
//
void HUlib_initTextLine(hu_textline_t* t, int x, int y,
                        const patchnum_t* f, int sc, int cm  )
//jff 2/16/98 add color range parameter
{
   t->x = x;
   t->y = y;
   t->f = f;
   t->sc = sc;
   t->cm = cm;
   HUlib_clearTextLine(t);
}

//
// HUlib_addCharToTextLine()
//
// Adds a character at the end of the text line in a hu_textline_t widget
//
// Passed the hu_textline_t and the char to add
// Returns false if already at length limit, true if the character added
//
boolean HUlib_addCharToTextLine
( hu_textline_t*  t,
  char      ch )
{
   // killough 1/23/98 -- support multiple lines
   if (t->linelen == HU_MAXLINELENGTH)
      return false;
   else
   {
      t->linelen++;
      if (ch == '\n')
         t->linelen=0;

      t->l[t->len++] = ch;
      t->l[t->len] = 0;
      t->needsupdate = 4;
      return true;
   }

}

//
// HUlib_delCharFromTextLine()
//
// Deletes a character at the end of the text line in a hu_textline_t widget
//
// Passed the hu_textline_t
// Returns false if already empty, true if the character deleted
//
boolean HUlib_delCharFromTextLine(hu_textline_t* t)
{
   if (!t->len) return false;
   else
   {
      t->l[--t->len] = 0;
      t->needsupdate = 4;
      return true;
   }
}

//
// HUlib_drawTextLine()
//
// Draws a hu_textline_t widget
//
// Passed the hu_textline_t and flag whether to draw a cursor
// Returns nothing
//
void HUlib_drawTextLine
( hu_textline_t* l,
  boolean drawcursor )
{

   int     i;
   int     w;
   int     x;
   unsigned char c;
   int oc = l->cm; //jff 2/17/98 remember default color
   int y = l->y;           // killough 1/18/98 -- support multiple lines

   // draw the new stuff
   x = l->x;
   for (i=0;i<l->len;i++)
   {
      c = toupper(l->l[i]); //jff insure were not getting a cheap toupper conv.

      if (c=='\n')         // killough 1/18/98 -- support multiple lines
         x=0,y+=8;
      else if (c=='\t')    // killough 1/23/98 -- support tab stops
         x=x-x%80+80;
      else if (c=='\x1b')  //jff 2/17/98 escape code for color change
      {                    //jff 3/26/98 changed to actual escape char
         if (++i<l->len)
            if (l->l[i]>='0' && l->l[i]<='9')
               l->cm = l->l[i]-'0';
      }
      else  if (c != ' ' && c >= l->sc && c <= 127)
      {
         w = SHORT(l->f[c - l->sc].width);
         if (x+w > BASE_WIDTH)
            break;
         // killough 1/18/98 -- support multiple lines:
         // CPhipps - patch drawing updated
         V_DrawNumPatch(x, y, FG, l->f[c - l->sc].lumpnum, l->cm, VPT_TRANS | VPT_STRETCH);
         x += w;
      }
      else
      {
         x += 4;
         if (x >= BASE_WIDTH)
            break;
      }
   }
   l->cm = oc; //jff 2/17/98 restore original color

   // draw the cursor if requested
   if (drawcursor && x + SHORT(l->f['_' - l->sc].width) <= BASE_WIDTH)
   {
      // killough 1/18/98 -- support multiple lines
      // CPhipps - patch drawing updated
      V_DrawNumPatch(x, y, FG, l->f['_' - l->sc].lumpnum, CR_DEFAULT, VPT_NONE | VPT_STRETCH);
   }
}

//
// HUlib_eraseTextLine()
//
// Erases a hu_textline_t widget when screen border is behind text
// Sorta called by HU_Erase and just better darn get things straight
//
// Passed the hu_textline_t
// Returns nothing
//
void HUlib_eraseTextLine(hu_textline_t* l)
{
// KK - If someone finds a use for this code, please fix it, I havn't seen the need
//      And it's not written to take into account scaling.  Causing some nasty effects
//      on smaller screens.
   (void)l;
#if 0
   int lh;
   int y;
   int yoffset;

   // Only erases when NOT in automap and the screen is reduced,
   // and the text must either need updating or refreshing
   // (because of a recent change back from the automap)

   if (!(automapmode & am_active) && viewwindowx && l->needsupdate)
   {
      lh = SHORT(l->f[0].height) + 1;
      for (y=l->y,yoffset=y*SCREENWIDTH ; y<l->y+lh ; y++,yoffset+=SCREENWIDTH)
      {
         if (y < viewwindowy || y >= viewwindowy + viewheight)
            R_VideoErase(yoffset, SCREENWIDTH); // erase entire line
         else
         {
            // erase left border
            R_VideoErase(yoffset, viewwindowx);
            // erase right border
            R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
         }
      }
   }
   if (l->needsupdate) l->needsupdate--;
#endif
}

////////////////////////////////////////////////////////
//
// Player message widget (up to 4 lines of text)
//
////////////////////////////////////////////////////////

//
// HUlib_initSText()
//
// Initialize a hu_stext_t widget. Set the position, number of lines, font,
// start char of the font, and color range to be used, and whether enabled.
//
// Passed a hu_stext_t, and the values used to initialize
// Returns nothing
//
void HUlib_initSText
( hu_stext_t* s,
  int   x,
  int   y,
  int   h,
  const patchnum_t* font,
  int   startchar,
  int cm,       //jff 2/16/98 add color range parameter
  boolean*  on )
{

   int i;

   s->h = h;
   s->on = on;
   s->laston = true;
   s->cl = 0;
   for (i=0;i<h;i++)
      HUlib_initTextLine
      (
         &s->l[i],
         x,
         y - i*(SHORT(font[0].height)+1),
         font,
         startchar,
         cm
      );
}

//
// HUlib_addLineToSText()
//
// Adds a blank line to a hu_stext_t widget
//
// Passed a hu_stext_t
// Returns nothing
//
void HUlib_addLineToSText(hu_stext_t* s)
{

   int i;

   // add a clear line
   if (++s->cl == s->h)
      s->cl = 0;
   HUlib_clearTextLine(&s->l[s->cl]);

   // everything needs updating
   for (i=0 ; i<s->h ; i++)
      s->l[i].needsupdate = 4;

}

//
// HUlib_addMessageToSText()
//
// Adds a message line with prefix to a hu_stext_t widget
//
// Passed a hu_stext_t, the prefix string, and a message string
// Returns nothing
//
void HUlib_addMessageToSText(hu_stext_t* s, const char* prefix, const char* msg)
{
   HUlib_addLineToSText(s);
   if (prefix)
      while (*prefix)
         HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++));

   while (*msg)
      HUlib_addCharToTextLine(&s->l[s->cl], *(msg++));
}

//
// HUlib_drawSText()
//
// Displays a hu_stext_t widget
//
// Passed a hu_stext_t
// Returns nothing
//
void HUlib_drawSText(hu_stext_t* s)
{
   int i, idx;
   hu_textline_t *l;

   if (!*s->on)
      return; // if not on, don't draw

   // draw everything
   for (i=0 ; i<s->h ; i++)
   {
      idx = s->cl - i;
      if (idx < 0)
         idx += s->h; // handle queue of lines

      l = &s->l[idx];

      // need a decision made here on whether to skip the draw
      HUlib_drawTextLine(l, false); // no cursor, please
   }
}

//
// HUlib_eraseSText()
//
// Erases a hu_stext_t widget, when the screen is not fullsize
//
// Passed a hu_stext_t
// Returns nothing
//
void HUlib_eraseSText(hu_stext_t* s)
{
   int i;

   for (i=0 ; i<s->h ; i++)
   {
      if (s->laston && !*s->on)
         s->l[i].needsupdate = 4;
      HUlib_eraseTextLine(&s->l[i]);
   }
   s->laston = *s->on;
}

////////////////////////////////////////////////////////
//
// Scrolling message review widget
//
// jff added 2/26/98
//
////////////////////////////////////////////////////////

//
// HUlib_initMText()
//
// Initialize a hu_mtext_t widget. Set the position, width, number of lines,
// font, start char of the font, color range, background font, and whether
// enabled.
//
// Passed a hu_mtext_t, and the values used to initialize
// Returns nothing
//
void HUlib_initMText(hu_mtext_t *m, int x, int y, int w, int h,
                     const patchnum_t* font, int startchar, int cm,
                     const patchnum_t* bgfont, boolean *on)
{
   int i;

   m->nl = 0;
   m->nr = 0;
   m->cl = -1; //jff 4/28/98 prepare for pre-increment
   m->x = x;
   m->y = y;
   m->w = w;
   m->h = h;
   m->bg = bgfont;
   m->on = on;
   for (i=0;i<HU_MAXMESSAGES;i++)
   {
      HUlib_initTextLine
      (
         &m->l[i],
         x,
         y + (hud_list_bgon? i+1 : i)*HU_REFRESHSPACING,
         font,
         startchar,
         cm
      );
   }
}

//
// HUlib_addLineToMText()
//
// Adds a blank line to a hu_mtext_t widget
//
// Passed a hu_mtext_t
// Returns nothing
//
void HUlib_addLineToMText(hu_mtext_t* m)
{
   // add a clear line