Make manual page rendering easier.
[jimtcl/wkoszek.git] / jim-sdl.c
blobbc8c36da16fce97590a685cf4cc0b9e8f49822a9
1 /* Jim - SDL extension
2 * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * A copy of the license is also included in the source distribution
11 * of Jim, as a TXT file name called LICENSE.
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <SDL.h>
25 #include <SDL_gfxPrimitives.h>
27 #define JIM_EXTENSION
28 #include "jim.h"
30 #define AIO_CMD_LEN 128
32 typedef struct JimSdlSurface {
33 SDL_Surface *screen;
34 } JimSdlSurface;
36 static void JimSdlSetError(Jim_Interp *interp)
38 Jim_SetResultString(interp, SDL_GetError(), -1);
41 static void JimSdlDelProc(Jim_Interp *interp, void *privData)
43 JimSdlSurface *jss = privData;
44 JIM_NOTUSED(interp);
46 SDL_FreeSurface(jss->screen);
47 Jim_Free(jss);
50 /* Calls to commands created via [sdl.surface] are implemented by this
51 * C command. */
52 static int JimSdlHandlerCommand(Jim_Interp *interp, int argc,
53 Jim_Obj *const *argv)
55 JimSdlSurface *jss = Jim_CmdPrivData(interp);
56 int option;
57 const char *options[] = {
58 "free", "flip", "pixel", "rectangle", "box", "line", "aaline",
59 "circle", "aacircle", "fcircle", NULL
61 enum {OPT_FREE, OPT_FLIP, OPT_PIXEL, OPT_RECTANGLE, OPT_BOX, OPT_LINE,
62 OPT_AALINE, OPT_CIRCLE, OPT_AACIRCLE, OPT_FCIRCLE};
64 if (argc < 2) {
65 Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?");
66 return JIM_ERR;
68 if (Jim_GetEnum(interp, argv[1], options, &option, "SDL surface method",
69 JIM_ERRMSG) != JIM_OK)
70 return JIM_ERR;
71 if (option == OPT_PIXEL) {
72 /* PIXEL */
73 long x, y, red, green, blue, alpha = 255;
75 if (argc != 7 && argc != 8) {
76 Jim_WrongNumArgs(interp, 2, argv, "x y red green blue ?alpha?");
77 return JIM_ERR;
79 if (Jim_GetLong(interp, argv[2], &x) != JIM_OK ||
80 Jim_GetLong(interp, argv[3], &y) != JIM_OK ||
81 Jim_GetLong(interp, argv[4], &red) != JIM_OK ||
82 Jim_GetLong(interp, argv[5], &green) != JIM_OK ||
83 Jim_GetLong(interp, argv[6], &blue) != JIM_OK)
85 return JIM_ERR;
87 if (argc == 8 && Jim_GetLong(interp, argv[7], &alpha) != JIM_OK)
88 return JIM_ERR;
89 pixelRGBA(jss->screen, x, y, red, green, blue, alpha);
90 return JIM_OK;
91 } else if (option == OPT_RECTANGLE || option == OPT_BOX ||
92 option == OPT_LINE || option == OPT_AALINE)
94 /* RECTANGLE, BOX, LINE, AALINE */
95 long x1, y1, x2, y2, red, green, blue, alpha = 255;
97 if (argc != 9 && argc != 10) {
98 Jim_WrongNumArgs(interp, 2, argv, "x y red green blue ?alpha?");
99 return JIM_ERR;
101 if (Jim_GetLong(interp, argv[2], &x1) != JIM_OK ||
102 Jim_GetLong(interp, argv[3], &y1) != JIM_OK ||
103 Jim_GetLong(interp, argv[4], &x2) != JIM_OK ||
104 Jim_GetLong(interp, argv[5], &y2) != JIM_OK ||
105 Jim_GetLong(interp, argv[6], &red) != JIM_OK ||
106 Jim_GetLong(interp, argv[7], &green) != JIM_OK ||
107 Jim_GetLong(interp, argv[8], &blue) != JIM_OK)
109 return JIM_ERR;
111 if (argc == 10 && Jim_GetLong(interp, argv[9], &alpha) != JIM_OK)
112 return JIM_ERR;
113 switch(option) {
114 case OPT_RECTANGLE:
115 rectangleRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha);
116 break;
117 case OPT_BOX:
118 boxRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha);
119 break;
120 case OPT_LINE:
121 lineRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha);
122 break;
123 case OPT_AALINE:
124 aalineRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha);
125 break;
127 return JIM_OK;
128 } else if (option == OPT_CIRCLE || option == OPT_AACIRCLE ||
129 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,
136 "x y radius red green blue ?alpha?");
137 return JIM_ERR;
139 if (Jim_GetLong(interp, argv[2], &x) != JIM_OK ||
140 Jim_GetLong(interp, argv[3], &y) != JIM_OK ||
141 Jim_GetLong(interp, argv[4], &radius) != JIM_OK ||
142 Jim_GetLong(interp, argv[5], &red) != JIM_OK ||
143 Jim_GetLong(interp, argv[6], &green) != JIM_OK ||
144 Jim_GetLong(interp, argv[7], &blue) != JIM_OK)
146 return JIM_ERR;
148 if (argc == 9 && Jim_GetLong(interp, argv[8], &alpha) != JIM_OK)
149 return JIM_ERR;
150 switch(option) {
151 case OPT_CIRCLE:
152 circleRGBA(jss->screen, x, y, radius, red, green, blue, alpha);
153 break;
154 case OPT_AACIRCLE:
155 aacircleRGBA(jss->screen, x, y, radius, red, green, blue, alpha);
156 break;
157 case OPT_FCIRCLE:
158 filledCircleRGBA(jss->screen, x, y, radius, red, green, blue,
159 alpha);
160 break;
162 return JIM_OK;
163 } else if (option == OPT_FREE) {
164 /* FREE */
165 if (argc != 2) {
166 Jim_WrongNumArgs(interp, 2, argv, "");
167 return JIM_ERR;
169 Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL));
170 return JIM_OK;
171 } else if (option == OPT_FLIP) {
172 /* FLIP */
173 if (argc != 2) {
174 Jim_WrongNumArgs(interp, 2, argv, "");
175 return JIM_ERR;
177 SDL_Flip(jss->screen);
178 return JIM_OK;
180 return JIM_OK;
183 static int JimSdlSurfaceCommand(Jim_Interp *interp, int argc,
184 Jim_Obj *const *argv)
186 JimSdlSurface *jss;
187 char buf[AIO_CMD_LEN];
188 Jim_Obj *objPtr;
189 long screenId, xres, yres;
190 SDL_Surface *screen;
192 if (argc != 3) {
193 Jim_WrongNumArgs(interp, 1, argv, "xres yres");
194 return JIM_ERR;
196 if (Jim_GetLong(interp, argv[1], &xres) != JIM_OK ||
197 Jim_GetLong(interp, argv[2], &yres) != JIM_OK)
198 return JIM_ERR;
200 /* Try to create the surface */
201 screen = SDL_SetVideoMode(xres, yres, 32, SDL_SWSURFACE|SDL_ANYFORMAT);
202 if (screen == NULL) {
203 JimSdlSetError(interp);
204 return JIM_ERR;
206 /* Get the next file id */
207 if (Jim_EvalGlobal(interp,
208 "if {[catch {incr sdl.surfaceId}]} {set sdl.surfaceId 0}") != JIM_OK)
209 return JIM_ERR;
210 objPtr = Jim_GetVariableStr(interp, "sdl.surfaceId", JIM_ERRMSG);
211 if (objPtr == NULL) return JIM_ERR;
212 if (Jim_GetLong(interp, objPtr, &screenId) != JIM_OK) return JIM_ERR;
214 /* Create the SDL screen command */
215 jss = Jim_Alloc(sizeof(*jss));
216 jss->screen = screen;
217 sprintf(buf, "sdl.surface%ld", screenId);
218 Jim_CreateCommand(interp, buf, JimSdlHandlerCommand, jss, JimSdlDelProc);
219 Jim_SetResultString(interp, buf, -1);
220 return JIM_OK;
223 int Jim_OnLoad(Jim_Interp *interp)
225 Jim_InitExtension(interp);
226 if (Jim_PackageProvide(interp, "sdl", "1.0", JIM_ERRMSG) != JIM_OK)
227 return JIM_ERR;
228 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
229 JimSdlSetError(interp);
230 return JIM_ERR;
232 atexit(SDL_Quit);
233 Jim_CreateCommand(interp, "sdl.screen", JimSdlSurfaceCommand, NULL, NULL);
234 return JIM_OK;