Document [string map]
[jimtcl.git] / jim-sdl.c
blob2e700eb21c7d8c959bd9e5cf2a5af6577aba7ca4
2 /* Jim - SDL extension
3 * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * A copy of the license is also included in the source distribution
12 * of Jim, as a TXT file name called LICENSE.
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <SDL/SDL.h>
26 #include <SDL/SDL_gfxPrimitives.h>
28 #include "jim.h"
29 #include "jimautoconf.h"
31 #define AIO_CMD_LEN 128
33 typedef struct JimSdlSurface
35 SDL_Surface *screen;
36 } JimSdlSurface;
38 static void JimSdlSetError(Jim_Interp *interp)
40 Jim_SetResultString(interp, SDL_GetError(), -1);
43 static void JimSdlDelProc(Jim_Interp *interp, void *privData)
45 JimSdlSurface *jss = privData;
47 JIM_NOTUSED(interp);
49 SDL_FreeSurface(jss->screen);
50 Jim_Free(jss);
53 /* Calls to commands created via [sdl.surface] are implemented by this
54 * C command. */
55 static int JimSdlHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
57 JimSdlSurface *jss = Jim_CmdPrivData(interp);
58 int option;
59 static const char * const options[] = {
60 "free", "flip", "pixel", "rectangle", "box", "line", "aaline",
61 "circle", "aacircle", "fcircle", NULL
63 enum
64 { OPT_FREE, OPT_FLIP, OPT_PIXEL, OPT_RECTANGLE, OPT_BOX, OPT_LINE,
65 OPT_AALINE, OPT_CIRCLE, OPT_AACIRCLE, OPT_FCIRCLE
68 if (argc < 2) {
69 Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?");
70 return JIM_ERR;
72 if (Jim_GetEnum(interp, argv[1], options, &option, "SDL surface method", JIM_ERRMSG) != JIM_OK)
73 return JIM_ERR;
74 if (option == OPT_PIXEL) {
75 /* PIXEL */
76 long x, y, red, green, blue, alpha = 255;
78 if (argc != 7 && argc != 8) {
79 Jim_WrongNumArgs(interp, 2, argv, "x y red green blue ?alpha?");
80 return JIM_ERR;
82 if (Jim_GetLong(interp, argv[2], &x) != JIM_OK ||
83 Jim_GetLong(interp, argv[3], &y) != JIM_OK ||
84 Jim_GetLong(interp, argv[4], &red) != JIM_OK ||
85 Jim_GetLong(interp, argv[5], &green) != JIM_OK ||
86 Jim_GetLong(interp, argv[6], &blue) != JIM_OK) {
87 return JIM_ERR;
89 if (argc == 8 && Jim_GetLong(interp, argv[7], &alpha) != JIM_OK)
90 return JIM_ERR;
91 pixelRGBA(jss->screen, x, y, red, green, blue, alpha);
92 return JIM_OK;
94 else if (option == OPT_RECTANGLE || option == OPT_BOX ||
95 option == OPT_LINE || option == OPT_AALINE) {
96 /* RECTANGLE, BOX, LINE, AALINE */
97 long x1, y1, x2, y2, red, green, blue, alpha = 255;
99 if (argc != 9 && argc != 10) {
100 Jim_WrongNumArgs(interp, 2, argv, "x y red green blue ?alpha?");
101 return JIM_ERR;
103 if (Jim_GetLong(interp, argv[2], &x1) != JIM_OK ||
104 Jim_GetLong(interp, argv[3], &y1) != JIM_OK ||
105 Jim_GetLong(interp, argv[4], &x2) != JIM_OK ||
106 Jim_GetLong(interp, argv[5], &y2) != JIM_OK ||
107 Jim_GetLong(interp, argv[6], &red) != JIM_OK ||
108 Jim_GetLong(interp, argv[7], &green) != JIM_OK ||
109 Jim_GetLong(interp, argv[8], &blue) != JIM_OK) {
110 return JIM_ERR;
112 if (argc == 10 && Jim_GetLong(interp, argv[9], &alpha) != JIM_OK)
113 return JIM_ERR;
114 switch (option) {
115 case OPT_RECTANGLE:
116 rectangleRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha);
117 break;
118 case OPT_BOX:
119 boxRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha);
120 break;
121 case OPT_LINE:
122 lineRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha);
123 break;
124 case OPT_AALINE:
125 aalineRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha);
126 break;
128 return JIM_OK;
130 else if (option == OPT_CIRCLE || option == OPT_AACIRCLE || option == OPT_FCIRCLE) {
131 /* CIRCLE, AACIRCLE, FCIRCLE */
132 long x, y, radius, red, green, blue, alpha = 255;
134 if (argc != 8 && argc != 9) {
135 Jim_WrongNumArgs(interp, 2, argv, "x y radius red green blue ?alpha?");
136 return JIM_ERR;
138 if (Jim_GetLong(interp, argv[2], &x) != JIM_OK ||
139 Jim_GetLong(interp, argv[3], &y) != JIM_OK ||
140 Jim_GetLong(interp, argv[4], &radius) != JIM_OK ||
141 Jim_GetLong(interp, argv[5], &red) != JIM_OK ||
142 Jim_GetLong(interp, argv[6], &green) != JIM_OK ||
143 Jim_GetLong(interp, argv[7], &blue) != JIM_OK) {
144 return JIM_ERR;
146 if (argc == 9 && Jim_GetLong(interp, argv[8], &alpha) != JIM_OK)
147 return JIM_ERR;
148 switch (option) {
149 case OPT_CIRCLE:
150 circleRGBA(jss->screen, x, y, radius, red, green, blue, alpha);
151 break;
152 case OPT_AACIRCLE:
153 aacircleRGBA(jss->screen, x, y, radius, red, green, blue, alpha);
154 break;
155 case OPT_FCIRCLE:
156 filledCircleRGBA(jss->screen, x, y, radius, red, green, blue, alpha);
157 break;
159 return JIM_OK;
161 else if (option == OPT_FREE) {
162 /* FREE */
163 if (argc != 2) {
164 Jim_WrongNumArgs(interp, 2, argv, "");
165 return JIM_ERR;
167 Jim_DeleteCommand(interp, Jim_String(argv[0]));
168 return JIM_OK;
170 else if (option == OPT_FLIP) {
171 /* FLIP */
172 if (argc != 2) {
173 Jim_WrongNumArgs(interp, 2, argv, "");
174 return JIM_ERR;
176 SDL_Flip(jss->screen);
177 return JIM_OK;
179 return JIM_OK;
182 static int JimSdlSurfaceCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
184 JimSdlSurface *jss;
185 char buf[AIO_CMD_LEN];
186 Jim_Obj *objPtr;
187 long screenId, xres, yres;
188 SDL_Surface *screen;
190 if (argc != 3) {
191 Jim_WrongNumArgs(interp, 1, argv, "xres yres");
192 return JIM_ERR;
194 if (Jim_GetLong(interp, argv[1], &xres) != JIM_OK ||
195 Jim_GetLong(interp, argv[2], &yres) != JIM_OK)
196 return JIM_ERR;
198 /* Try to create the surface */
199 screen = SDL_SetVideoMode(xres, yres, 32, SDL_SWSURFACE | SDL_ANYFORMAT);
200 if (screen == NULL) {
201 JimSdlSetError(interp);
202 return JIM_ERR;
204 /* Get the next file id */
205 if (Jim_EvalGlobal(interp, "if {[catch {incr sdl.surfaceId}]} {set sdl.surfaceId 0}") != JIM_OK)
206 return JIM_ERR;
207 objPtr = Jim_GetVariableStr(interp, "sdl.surfaceId", JIM_ERRMSG);
208 if (objPtr == NULL)
209 return JIM_ERR;
210 if (Jim_GetLong(interp, objPtr, &screenId) != JIM_OK)
211 return JIM_ERR;
213 /* Create the SDL screen command */
214 jss = Jim_Alloc(sizeof(*jss));
215 jss->screen = screen;
216 sprintf(buf, "sdl.surface%ld", screenId);
217 Jim_CreateCommand(interp, buf, JimSdlHandlerCommand, jss, JimSdlDelProc);
218 Jim_SetResultString(interp, buf, -1);
219 return JIM_OK;
222 int Jim_sdlInit(Jim_Interp *interp)
224 if (Jim_PackageProvide(interp, "sdl", "1.0", JIM_ERRMSG))
225 return JIM_ERR;
227 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
228 JimSdlSetError(interp);
229 return JIM_ERR;
231 atexit(SDL_Quit);
232 Jim_CreateCommand(interp, "sdl.screen", JimSdlSurfaceCommand, NULL, NULL);
233 return JIM_OK;