summaryrefslogtreecommitdiff
path: root/apps/plugins/xworld/xworld.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/xworld/xworld.c')
-rw-r--r--apps/plugins/xworld/xworld.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/apps/plugins/xworld/xworld.c b/apps/plugins/xworld/xworld.c
new file mode 100644
index 0000000000..932ff1c3e1
--- /dev/null
+++ b/apps/plugins/xworld/xworld.c
@@ -0,0 +1,244 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 Franklin Wei, Benjamin Brown
11 * Copyright (C) 2004 Gregory Montoir
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23#include "plugin.h"
24#include "engine.h"
25#include "sys.h"
26#include "util.h"
27
28/* we don't want these on the stack, they're big and could cause a stack overflow */
29static struct Engine e;
30static struct System sys;
31
32enum plugin_status plugin_start(const void* parameter)
33{
34 (void) parameter;
35
36 /* no trailing slashes */
37 const char *dataPath = "/.rockbox/xworld";
38 const char *savePath = "/.rockbox/xworld";
39 g_debugMask = 0;
40
41 engine_create(&e, &sys, dataPath, savePath);
42 engine_init(&e);
43 sys_menu(&sys);
44
45 engine_run(&e);
46
47 engine_finish(&e);
48 return PLUGIN_OK;
49}
50
51
52
53/*
54 Game was originally made with 16. SIXTEEN colors. Running on 320x200 (64,000 pixels.)
55
56 Great fan site here: https://sites.google.com/site/interlinkknight/anotherworld
57 Contains the wheelcode :P !
58
59 A lot of details can be found regarding the game and engine architecture at:
60 http://www.anotherworld.fr/anotherworld_uk/another_world.htm
61
62 The chronology of the game implementation can retraced via the ordering of the opcodes:
63 The sound and music opcode are at the end: Music and sound was done at the end.
64
65 Call tree:
66 =========
67
68 SDLSystem systemImplementaion ;
69 System *sys = & systemImplementaion ;
70
71 main
72 {
73
74 Engine *e = new Engine();
75 e->run()
76 {
77 sys->init("Out Of This World");
78 setup();
79 vm.restartAt(0x3E80); // demo starts at 0x3E81
80
81 while (!_stub->_pi.quit)
82 {
83 vm.setupScripts();
84 vm.inp_updatePlayer();
85 processInput();
86 vm.runScripts();
87 }
88
89 finish();
90 }
91 }
92
93
94 Virtual Machine:
95 ================
96
97 Seems the threading model is collaborative multi-tasking (as opposed to preemptive multitasking):
98 A thread (called a Channel on Eric Chahi's website) will release the hand to the next one via the
99 break opcode.
100
101 It seems that even when a setvec is requested by a thread, we cannot set the instruction pointer
102 yet. The thread is allowed to keep on executing its code for the remaining of the vm frame.
103
104 A virtual machine frame has a variable duration. The unit of time is 20ms and the frame can be set
105 to live for 1 (20ms ; 50Hz) up to 5 (100ms ; 10Hz).
106
107
108 There are 30 something opcodes. The graphic opcode are more complex, not only the declare the operation to perform
109 they also define where to find the vertices (segVideo1 or segVideo2).
110
111 No stack available but a thread can save its pc (Program Counter) once: One method call and return is possible.
112
113
114 Video :
115 =======
116 Double buffer architecture. AW opcodes even has a special instruction for blitting from one
117 frame buffer to an other.
118
119 Double buffering is implemented in software
120
121 According to Eric Chahi's webpage there are 4 framebuffer. Since on full screenbuffer is 320x200/2 = 32kB
122 that would mean the total size consumed is 128KB ?
123
124 Sound :
125 =======
126 Mixing is done on software.
127
128 Since the virtual machine and SDL are running simultaneously in two different threads:
129 Any read or write to an elements of the sound channels MUST be synchronized with a
130 mutex.
131
132 FastMode :
133 ==========
134
135 The game engine features a "fast-mode"...what it to be able to respond to the now defunct
136 TURBO button commonly found on 386/486 era PC ?!
137
138
139 Endianess:
140 ==========
141
142 Atari and Amiga used bigEndian CPUs. Data are hence stored within BANK in big endian format.
143 On an Intel or ARM CPU data will have to be transformed when read.
144
145
146
147 The original codebase contained a looooot of cryptic hexa values.
148 0x100 (for 256 variables)
149 0x400 (for one kilobyte)
150 0x40 (for num threads)
151 0x3F (num thread mask)
152 I cleaned that up.
153
154 Questions & Answers :
155 =====================
156
157 Q: How does the interpreter deals with the CPU speed ?! A pentium is a tad faster than a Motorola 68000
158 after all.
159 A: See vm frame time: The vm frame duration is variable. The vm actually write for how long a video frame
160 should be displayed in variable 0xFF. The value is the number of 20ms slice
161
162 Q: Why is a palette 2048 bytes if there are only 16 colors ? I would have expected 48 bytes...
163 A: ???
164
165 Q: Why does Resource::load() search for ressource to load from higher to lower....since it will load stuff
166 until no more ressources are marked as "Need to be loaded".
167 A: ???
168
169 Original DOS version :
170 ======================
171
172 Banks: 1,236,519 B
173 exe : 20,293 B
174
175
176 Total bank size: 1236519 (100%)
177 ---------------------------------
178 Total RT_SOUND size: 585052 ( 47%)
179 Total RT_MUSIC size: 3540 ( 0%)
180 Total RT_POLY_ANIM size: 106676 ( 9%)
181 Total RT_PALETTE size: 11032 ( 1%)
182 Total RT_BYTECODE size: 135948 ( 11%)
183 Total RT_POLY_CINEMATIC size: 291008 ( 24%)
184
185 As usual sounds are the most consuming assets (Quake1,Quake2 etc.....)
186
187
188 memlist.bin features 146 entries :
189 ==================================
190
191 Most important part in an entry are:
192
193 bankId : - Give the file were the resource is.
194 offset : - How much to skip in the file before hiting the resource.
195 size,packetSize : - How much to read, should we unpack what we read.
196
197
198
199 Polygons drawing :
200 =================
201
202 Polygons can be given as:
203 - a pure screenspace sequence of points: I call those screenspace polygons.
204 - a list of delta to add or substract to the first vertex. I call those: objectspace polygons.
205
206 Video :
207 =======
208
209 Q: Why 4 framebuffer ?
210 A: It seems the background is generated once (like in the introduction) and stored in a framebuffer.
211 Every frame the saved background is copied and new elements are drawn on top.
212
213
214 Trivia :
215 ========
216
217 If you are used to RGBA 32bits per pixel framebuffer you are in for a shock:
218 Another world is 16 colors palette based, making it 4bits per pixel !!
219
220 Video generation :
221 ==================
222
223 Thank god the engine sets the palette before starting to drawing instead of after bliting.
224 I would have been unable to generate screenshots otherwise.
225
226 Memory managment :
227 =================
228
229 There is 0 malloc during the game. All resources are loaded in one big buffer (Resource::load).
230 The entire buffer is "freed" at the end of a game part.
231
232
233 The renderer is actually capable of Blending a new poly in the framebuffer (Video::drawLineT)
234
235
236 I am almost sure that:
237 _curPagePtr1 is the backbuffer
238 _curPagePtr2 is the frontbuffer
239 _curPagePtr3 is the background builder.
240
241
242 * Why does memlist.bin uses a special state field 0xFF in order to mark the end of resources ??!
243 It would have been so much easier to write the number of resources at the beginning of the code.
244*/